我有一个TCP聊天程序:
服务器在一个
现在我想知道如何做到这一点。我绝对需要每个已接受的连接都在一个线程中。
我考虑在
编辑:添加代码 我的代码:
server.c
和client.c
。服务器在一个
while(1)
循环中运行,并使用select
检测想要连接到其套接字的客户端。然后为已接受的客户端创建一个新线程,并将其套接字描述符作为线程参数传递:pthread_create(&thread,NULL, do_something,(void *) &socket_descriptor);
当从客户端接收到消息时,服务器应将此消息发送到所有连接的客户端(尚未实现)。现在我想知道如何做到这一点。我绝对需要每个已接受的连接都在一个线程中。
我考虑在
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:我是这样解决的: 我有一个动态数组列表,其中放置了一组已连接客户端和它们的套接字描述符。在服务器线程(做某些事情)中,我有一个接收阻塞,直到它获得输入,然后使用从列表循环遍历的套接字描述符将此输入发送到所有已连接的客户端。在客户端中,存在一个正在侦听的线程和一个正在发送的线程。