我有一个 tcp 聊天程序:server.c
和client.c
.
服务器处于一个while(1)
循环中,用于select
检测想要连接它的套接字的客户端。然后为接受的客户端创建一个新线程,并将其套接字描述符作为线程的参数给出:pthread_create (&thread,NULL, do_something, (void *) &socket_descriptor);
当接收到来自客户端的消息时,服务器应该将此消息发送给所有连接的客户端。(尚未实施)。
现在我想知道如何做到这一点。我绝对需要每个接受的连接都在一个线程中。
我也在考虑使用select
inside 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),而是因为在分配中必须为每个客户端都有一个线程。
我遇到的具体问题是,只有主线程可以将每个线程中从每个客户端接收到的数据发送到所有客户端,因为只有主线程可以访问包含套接字描述符的集合。
编辑3:我需要在每个线程中添加什么,但我不能因为 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:我以这种方式解决了它:我有一个动态数组列表,我在其中放置了一个带有套接字描述符的已连接客户端列表。在服务器的线程内(做某事)我有接收阻塞,直到它得到输入然后这个输入被发送到所有连接的客户端,使用它循环通过的列表中的套接字描述符。在客户端内部有一个线程监听和一个线程发送。