c言語のチャットプログラムのsendとrecv
現在、複数のクライアントからサーバーにメッセージを送りサーバーからクライアントにメッセージを送るというものを作成しているのですが、クライアントからサーバーにはメッセージを送れるのですが、サーバー側からクライアント1人にしか送れず、クライアント全員にメッセージを送信できませんので、よろしければアドバイスをお願いします
サーバーのプログラム
インクルード省略
#define BUF_LEN 256
typedef struct CLIENT_INFO {
char hostname[BUF_LEN];
char ipaddr[BUF_LEN];
int port;
time_t last_access;
} CLIENT_INFO;
CLIENT_INFO client_info[FD_SETSIZE];
int listening_socket;
struct sockaddr_in sn;
int
accept_new_client(int sock){
int len;
int new_socket;
struct hostent *peer_host;
struct sockaddr_in peer_sin;
len = sizeof(sn);
new_socket = accept(listening_socket, (struct sockaddr *)&sn, &len);
if ( new_socket == -1 ){
perror("accept");
exit(1);
}
if ( new_socket > FD_SETSIZE-1 ){
return -1;
}
len = sizeof(peer_sin);
getpeername(new_socket,
(struct sockaddr *)&peer_sin, &len);
peer_host = gethostbyaddr((char *)&peer_sin.sin_addr.s_addr,
sizeof(peer_sin.sin_addr), AF_INET);
strncpy(client_info[new_socket].hostname, peer_host->h_name,
sizeof client_info[new_socket].hostname);
strncpy(client_info[new_socket].ipaddr, inet_ntoa(peer_sin.sin_addr),
sizeof client_info[new_socket].ipaddr);
client_info[new_socket].port = ntohs(peer_sin.sin_port);
time(&client_info[new_socket].last_access);
printf("接続: %s (%s) ポート %d ディスクリプタ %d 番\n",
client_info[new_socket].hostname,
client_info[new_socket].ipaddr,
client_info[new_socket].port,
new_socket);
return new_socket;
}
int
read_and_reply(int sock){
int read_size;
char buf[BUF_LEN];
read_size = read(sock, buf, sizeof(buf)-1);
if ( read_size == 0 || read_size == -1 ){
printf("%s (%s) ポート %d ディスクリプタ %d 番からの接続が切れました。\n",
client_info[sock].hostname,
client_info[sock].ipaddr,
client_info[sock].port,
sock);
close(sock);
client_info[sock].last_access = 0;
} else {
buf[read_size] = '\0';
printf("%s (%s) ポート %d ディスクリプタ %d 番からのメッセージ: %s",
client_info[sock].hostname,
client_info[sock].ipaddr,
client_info[sock].port,
sock,
buf);
write(sock, buf, strlen(buf));
time(&client_info[sock].last_access);
}
return read_size;
}
int
main(){
fd_set target_fds;
fd_set org_target_fds;
int sock_optval = 1;
int port = 5000;
listening_socket = socket(AF_INET, SOCK_STREAM, 0);
if ( setsockopt(listening_socket, SOL_SOCKET, SO_REUSEADDR,
&sock_optval, sizeof(sock_optval)) == -1 ){
perror("setsockopt");
exit(1);
}
sn.sin_family = AF_INET;
sn.sin_port = htons(port);
sn.sin_addr.s_addr = htonl(INADDR_ANY);
if ( bind(listening_socket, (struct sockaddr *)&sn, sizeof(sn)) < 0 ){
perror("bind");
exit(1);
}
if ( listen(listening_socket, SOMAXCONN) == -1 ){
perror("listen");
exit(1);
printf("ポート %d を見張ります。\n", port);
FD_ZERO(&org_target_fds);
FD_SET(listening_socket, &org_target_fds);
while (1){
int i;
time_t now_time;
struct timeval waitval;
waitval.tv_sec = 2;
waitval.tv_usec = 500;
memcpy(&target_fds, &org_target_fds, sizeof(org_target_fds));
select(FD_SETSIZE, &target_fds, NULL, NULL, &waitval);
for ( i=0 ; i<FD_SETSIZE ; i++ )
{
if ( FD_ISSET(i, &target_fds) )
{
printf("ディスクリプタ %d 番が読み込み可能です。\n", i);
if ( i == listening_socket )
{
int new_sock;
new_sock = accept_new_client(i);
if ( new_sock != -1 )
{
FD_SET(new_sock, &org_target_fds);
}
} else
{int read_size;
read_size = read_size;
read_size = read_and_reply(i);
if ( read_size == -1 || read_size == 0 )
{
FD_CLR(i, &org_target_fds);
}
}
}
}
time(&now_time);
for ( i=0 ; i<FD_SETSIZE ; i++){
if ( ! FD_ISSET(i, &org_target_fds) ) continue;
if ( i == listening_socket ) continue;
if ( now_time-60 > client_info[i].last_access )
{
close(i);
FD_CLR(i, &org_target_fds);
}
}
}
close(listening_socket);
FD_CLR(i, &org_target_fds);
}
}
補足
早速の回答ありがとうございます。 select関数は試していたのですが、select関数でも同様に フリーズが起きてしまっています。 デバッグしてみても、select関数の文で動作がとまってしまいます。