私はtcpチャットプログラムを持っています:server.c
そしてclient.c
。
サーバーはwhile(1)
ループ状態にあり、select
そのソケットに接続したいクライアントを検出するために使用します。次に、受け入れられたクライアント用に新しいスレッドが作成され、そのソケット記述子がスレッドの引数として指定されます。pthread_create (&thread,NULL, do_something, (void *) &socket_descriptor);
クライアントからメッセージを受信する場合、サーバーはこのメッセージを接続されているすべてのクライアントに送信する必要があります。(これはまだ実装されていません)。
今、私はこれをどのように行うのか疑問に思っています。受け入れられた各接続をスレッドに含める必要があります。
select
内部も使うことを考えてdo_something
いました。select
データがソケット記述子に着信しているかどうかを検出しますか?それとも別の方法でやりますか?
編集:追加されたコード私のコード:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include "tcp_comm.h"
#include <sys/time.h>
#include <sys/types.h>
#define BUFSIZE 1024
#define PORT 1234
void *do_something(void *a);
int main (void){
Socket server = tcp_passive_open( PORT );
MySocket *s = (MySocket *)server;
printf("Server socked_id (main): %i", s->sd);
pthread_t thread;
fd_set active_socketDescriptors,read_socketDescriptors;
FD_ZERO(&active_socketDescriptors);
FD_SET(s->sd,&active_socketDescriptors);
while (1){
read_socketDescriptors = active_socketDescriptors;
if (select (FD_SETSIZE, &read_socketDescriptors, NULL, NULL, NULL) < 0){
perror ("select");
exit (EXIT_FAILURE);
}
int i;
for (i = 0; i < FD_SETSIZE; ++i){
if (FD_ISSET (i, &read_socketDescriptors)){
if (i == s->sd){
Socket client = tcp_wait_for_connection( server );
pthread_create (&thread,NULL, do_something, (void *)client);
FD_SET (s->sd, &active_socketDescriptors);
} else {
}
}
}
}
tcp_close( server );
return 0;
}
void *do_something(void *client){
unsigned char input[BUFFER_SIZE];
pthread_detach(pthread_self());
MySocket *s = (MySocket *)client;
printf("Client socked_id (thread): %i", s->sd);
int j;
while (1){
int nbytes = tcp_receive(client, input, BUFSIZE );
if (nbytes <= 0){
if (nbytes ==0){
/* connection closed by client*/
printf("Client closed connection");
} else {
/* other error*/
perror("tcp_receive");
}
tcp_close(&client);
/*remove the socket descriptor from set in the main BRAINSTORM ABOUT THIS */
} else {
/*data incoming */
printf("\nMessage from client: %s",input);
}
}
return 0;
}
編集2:問題の再定式化私はスレッドを使用する必要があります(システムのためではなく、Linuxのためです)が、割り当てではクライアントごとにスレッドを持つことが必須であるためです。
私が特に抱えている問題は、メインスレッドだけがソケット記述子を含むセットにアクセスできるため、各スレッドで受信したデータを各クライアントからすべてのクライアントに送信できることです。
edit3:各スレッドに追加する必要があるものですが、s.threadとs.mainが異なる場所にあり、スレッドがメインのセットを認識していないため、追加できません。
for (j=0; j<=FD_SETSIZE;j++){
if(FD_ISSET(j,&active_socketDescriptors)){
if (j != s.thead && j!=s.main){
tcp_send(j, (void*)input,nbytes);
}
}
}
編集4:私はそれをこのように解決しました:私はそこにソケット記述子を持つ接続されたクライアントのリストを置く動的配列リストを持っています。サーバーのスレッド内で(何かを実行します)、入力を取得するまで受信をブロックします。その後、この入力は、ループするリストのソケット記述子を使用して、接続されているすべてのクライアントに送信されます。クライアントの内部には、スレッドのリスニングとスレッドの送信があります。