我必须从 15 个不同的客户端接收数据,每个客户端都在 5 个不同的端口上发送。总共15 * 5个插座。
为每个客户端端口号定义和固定。例如客户端 1,端口 3001 到 3005。客户端 2,端口 3051 到 3055 等。它们有一个共同点,即第一个端口(3001,3051)用于发送命令。其他端口发送一些数据。
收到数据后,我必须检查校验和。跟踪recvd数据包,如果丢失重新请求数据包,并且还必须写入硬盘上的文件。
限制我无法更改上述设计,也无法从 UDP 更改为 TCP。阅读后我知道的两种方法是
- 使用 select() 进行异步多路复用。
- 每个套接字的线程。
我尝试了第一个,但当我获取数据时,我被困在了这一点上。我能够接收数据。我有一些处理要做,所以我想为每个套接字(或)启动一个线程,让套接字处理(比如所有第一个端口,所有第二个端口等 ..ie3001,3051 等)但是在这里,如果客户端发送任何数据,则 FD_ISSET 变为是的,所以如果我启动一个线程,那么它就会成为每条消息的线程。 问题: 如何在此处添加线程代码,假设我在 if(FD_ISSET ..) 中包含 pthread_create,那么对于我收到的每条消息,我都会创建一个线程。但我想要每个套接字一个线程。
while(1)
{
int nready=0;
read_set = active_set;
if((nready = select(fdmax+1,&read_set,NULL,NULL,NULL)) == -1)
{
printf("Select Errpr\n");
perror("select");
exit(EXIT_FAILURE);
}
printf("number of ready desc=%d\n",nready);
for(index=1;index <= 15*5;index++)
{
if(FD_ISSET(sock_fd[index],&read_fd_set))
{
rc = recvfrom(sock_fd[index],clientmsgInfo,MSG_SIZE,0,
(struct sockaddr *)&client_sockaddr_in,
&sockaddr_in_length);
if(rc < 0)
printf("socket %d down\n",sock_fd[index]);
printf("Recieved packet from %s: %d\nData: %s\n\n", inet_ntoa(client_sockaddr_in.sin_addr), ntohs(client_sockaddr_in.sin_port), recv_client_message);
}
} //for
} //while