正しく理解したいのですが、提出期限が迫っているため、皆様の協力をいただき、以下の問題を解いてほしいです。
課題を提出した後、ゆっくりと理解したいと考えたいと思っていますので今はこれを解決していただけるでしょうか。
以下、問題と例のプログラムになります。
回答よろしくお願いします。
サーバ,あるいはクライアント起動時にハンドルネームを登録し,そのハンドル@マシン名" がメッセージ前に表示されるようにしてください.例えば,zenith にいるユーザが「Sasuke」と登録した場合,
\Sasuke@zenith: "
と全てのプロセスウィンドウに表示されるようにします.ただし,自分の打ち込んだメッセージの前には何も表示しません.
さらに、セッションの途中でもハンドルネームを変更できるようにしてください.例えば,ユーザtaro が"ch jiro " と打つとハンドルネームがjiro となるようにします.
ということなのですが、どこを改造すればいいでしょうか。よくわからないので申し訳ないですけど、詳しい回答よろしくおねがいします。
以下、改造しきれていないプログラムになります。
\\\\mchat_server.c\\\\
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<sys/time.h>
#include<unistd.h>
#include "echo2_common.h"
#define ERROR(x) do {fprintf(stderr, "-"); perror(x); exit(1);} while(0)
#define NUMCLIENT 5
#define ERR -1
#define UNUSED (-1)
void usage(void);
char *command_name;
int main(int argc, char *argv[])
{
int reqsd;
int sd[NUMCLIENT+1];
struct sockaddr_in server;
struct sockaddr_in client;
int fromlen;
int port;
char recv_buf[BUFSIZE];
char send_buf[BUFSIZE];
struct timeval timeout;
fd_set rfds;
int num_used_socket = 0;
int i, j;
int temp = 1;
int res;
int ret;
if ((command_name = rindex(argv[0], '/')) !=NULL)
command_name++;
else
command_name = argv[0];
if(argc != 2)
usage();
if( (reqsd = socket(PF_INET, SOCK_STREAM, 0)) == ERR)
ERROR("server: socket");
if (setsockopt(reqsd, SOL_SOCKET, SO_REUSEADDR, (void *)&temp, sizeof(temp)))
ERROR("server:setsockopt");
memset((void*)&server, 0, sizeof(server));
server.sin_family = PF_INET;
sscanf(argv[1], "%d", &port);
server.sin_port = htons(port);
server.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(reqsd, (struct sockaddr *)&server, sizeof(server)) == ERR)
ERROR("server: bind");
if(listen(reqsd, 5) == ERR)
ERROR("server: listen");
for (i=0; i<=NUMCLIENT; i++)
sd[i] = UNUSED;
do{
memset(recv_buf, '\0', BUFSIZE);
memset(send_buf, '\0', BUFSIZE);
FD_ZERO(&rfds);
if (reqsd != UNUSED ) FD_SET(reqsd, &rfds);
FD_SET(0, &rfds);
for (i=0; i<num_used_socket; i++){
if (sd[i] != UNUSED) FD_SET(sd[i], &rfds);
}
timeout.tv_sec = 0;
timeout.tv_usec = 1;
res = select(FD_SETSIZE, &rfds, NULL, NULL, &timeout);
if (res == ERR) ERROR("select");
if (FD_ISSET(reqsd, &rfds)){
memset((void *)&client, 0, sizeof(client));
fromlen = sizeof(client);
if ((sd[num_used_socket]
= accept(reqsd, (struct sockaddr *)&client, &fromlen))
== ERR )
ERROR("server: accept");
if (num_used_socket < NUMCLIENT)
num_used_socket++;
else {
strcpy(send_buf, "Server is too busy.\n");
WriteLine(sd[num_used_socket], send_buf);
WriteLine(sd[num_used_socket], "bye\n");
close(sd[num_used_socket]);
sd[num_used_socket] = UNUSED;
}
}
for(i=0; i<num_used_socket; i++){
if (sd[i] != UNUSED && FD_ISSET(sd[i],&rfds)){
ret = ReadLine(sd[i], recv_buf);
if (ret == ERR){
sprintf(send_buf, "client %d: connection closed.\n", i);
close(sd[i]);
sd[i] = UNUSED;
} else {
if (!strcmp(recv_buf, "quit\n")
|| !strcmp(recv_buf, "QUIT\n") ) {
strcpy(send_buf, recv_buf);
}
else if (!strcmp(recv_buf, "bye\n")
|| !strcmp(recv_buf, "BYE\n") ) {
sprintf(send_buf, "client %d: connection closed.\n", i);
close(sd[i]);
sd[i] = UNUSED;
}
else sprintf(send_buf, "from client %d: %s", i, recv_buf);
}
if (strlen(send_buf) > 0 ) {
WriteLine(1, send_buf);
for (j=0; j<num_used_socket; j++){
if ((j != i) && (sd[j] != UNUSED)) {
WriteLine(sd[j], send_buf);
}
}
}
if (!strcmp(recv_buf, "quit\n")
|| !strcmp(recv_buf, "QUIT\n") ) {
for (j=0; j<num_used_socket; j++){
close(sd[j]);
sd[j] = UNUSED;
}
close(reqsd);
exit(0);
}
}
}
if (FD_ISSET(0, &rfds)) {
if (ReadLine(0, recv_buf) == ERR) strcpy(recv_buf, "quit\n");
if (!strcmp(recv_buf, "quit\n") || !strcmp(recv_buf, "QUIT\n") )
strcpy(send_buf, recv_buf);
else
sprintf(send_buf, "from server: %s", recv_buf);
if (strlen(send_buf) > 0) {
for (j=0; j<num_used_socket; j++){
if (sd[j] != UNUSED)
WriteLine(sd[j], send_buf);
}
}
if (!strcmp(recv_buf, "quit\n") || !strcmp(recv_buf, "QUIT\n") ) {
for (j=0; j<num_used_socket; j++){
close(sd[j]);
sd[j] = UNUSED;
}
close(reqsd);
exit(0);
}
}
} while (1);
exit(0);
}
void usage(void)
{
fprintf(stderr, "Usage: %s PORT\n", command_name);
exit(1);
}
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<sys/time.h>
#include<unistd.h>
#include "echo2_common.h"
#define ERROR(x) do {fprintf(stderr, "-"); perror(x); exit(1);} while(0)
#define ERR -1
void usage(void);
char *command_name;
int main(int argc, char *argv[])
{
int sd;
struct sockaddr_in server;
struct hostent *hp;
int len;
int port;
char buf[BUFSIZE];
struct timeval timeout;
fd_set rfds;
int ret;
if ((command_name = rindex(argv[0], '/')) != NULL)
command_name++;
else
command_name = argv[0];
if (argc != 3)
usage();
if ((sd = socket(PF_INET, SOCK_STREAM, 0)) == ERR)
ERROR("client: socket");
memset((void*)&server, 0, sizeof(server));
server.sin_family = PF_INET;
port = atoi(argv[2]);
server.sin_port = htons(port);
if ((hp = gethostbyname(argv[1])) == NULL)
ERROR("client: gethostbyname");
memcpy(&(server.sin_addr), hp->h_addr_list[0], hp->h_length);
if (connect(sd, (struct sockaddr *)&server, sizeof(server)) == ERR)
ERROR("client: connect");
do {
memset(buf, '\0', BUFSIZE);
FD_ZERO(&rfds);
FD_SET(sd, &rfds);
FD_SET(0,&rfds);
timeout.tv_sec = 0;
timeout.tv_usec = 1;
if (select(sd+1, &rfds, NULL, NULL, &timeout) == ERR)
ERROR("select");
if (FD_ISSET(sd, &rfds)) {
if (ReadLine(sd, buf) == ERR) break;
WriteLine(1, buf);
if (strcmp(buf, "bye\n") || !strcmp(buf, "BYE\n")) break;
}
if (FD_ISSET(0, &rfds)) {
if (ReadLine(0, buf) == ERR) break;
WriteLine(sd, buf);
if (strcmp(buf, "bye\n") || !strcmp(buf, "BYE\n")) break;
}
} while (strcmp(buf, "quit\n") && strcmp(buf, "QUIT\n"));
close(sd);
exit(0);
}
void usage(void)
{
fprintf(stderr, "Usage: %s SERVER_NAME PORT\n", command_name);
exit(1);
}