ページ 11

C言語のネットワークプログラムの問題なのですが、この時点からどう改善すれば正しく動くかわかりません。

Posted: 2011年7月13日(水) 04:13
by サスケ
問題としては、
サーバ,あるいはクライアント起動時にハンドルネームを登録し,そのハンドル@マシン名" がメッセージ前に表示されるようにしてください.例えば,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 = 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 != UNUSED) FD_SET(sd, &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 != UNUSED && FD_ISSET(sd,&rfds)){
ret = ReadLine(sd, recv_buf);

if (ret == ERR){
sprintf(send_buf, "client %d: connection closed.\n", i);
close(sd);
sd = 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);
sd = 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);
}

\\\\mchat_client.c\\\\

#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);
}

\\\\echo2.common,h\\\\

#define BUFSIZE 1024
#define PORT 50951

int ReadLine(int sd, char *buf);

int WriteLine(int sd, char *buf);

Re: C言語のネットワークプログラムの問題なのですが、この時点からどう改善すれば正しく動くかわかりません。

Posted: 2011年7月13日(水) 04:35
by サスケ
すみません。こっちは見にくいです。
記事の削除の仕方がわかりません><
「編集」なんてどこにあるんですか!?

もう一度見やすいのを投稿させていただいたのでそちらの方をよろしくお願いします。

http://dixq.net/forum/viewtopic.php?f=3&t=8875