CSj*_*kie 1 c sockets select server
我正在编写一个连接到多个客户端的服务器.目前,我在SOCK_STREAM套接字上使用accept来连接新客户端.我希望能够接受发送数据报到服务器的SOCK_DGRAM套接字的客户端的查询.由于accept只是挂起,直到客户端发送连接到该套接字的请求,我需要一种方法来监视两个套接字,直到一个接收到来自客户端的请求,然后能够处理该请求并返回监视套接字.我不需要立即处理请求(即,如果客户端在另一个客户端请求连接查询客户端之后发送查询,则必须等待服务器完成连接客户端的请求,反之亦然).我知道套接字可以提醒服务器有多少套接字可以读/写,但是它如何告诉服务器哪个套接字已准备就绪?即哪个套接字已准备好读取,哪个可以写入?这是我的尝试,我知道监听器在连接后总是需要写入,而udpSock总是需要读取.
while(1){
retval = select(max,&readSockSet, &writeSockSet, NULL, &timeout);
if(retval){
if(FD_ISSET(listener, &writeSockSet))
printf("Client requesting to connect...\n");
if(FD_ISSET(udpSock, &readSockSet))
printf("Client query incoming...\n");
}
}
Run Code Online (Sandbox Code Playgroud)
accept()您可以使用select()告诉您何时客户端处于挂起状态,而不是阻止,这样您就可以accept()不受阻塞地进行呼叫.然后,您可以同时监视TCP和UDP套接字.您所拥有的代码已经在正确的轨道上完成该任务,但是您正在使用写入 fdset来检测何时accept()应该使用读取 fdset 来调用,并且您不会在每次循环迭代时重置fdsets或timeout为select()修改它们.
试试这个:
fd_set readSockSet;
timeval timeout;
int smax = max(listener, udpSock);
while (1)
{
FD_ZERO(&readSockSet);
FD_SET(listener, &readSockSet);
FD_SET(udpSock, &readSockSet);
// add connected TCP clients, if needed...
timeout.tv_sec = ...;
timeout.tv_usec = ...;
retval = select(smax+1, &readSockSet, NULL, NULL, &timeout);
if (retval > 0)
{
if (FD_ISSET(listener, &readSockSet))
{
printf("TCP Client requesting to connect...\n");
// call accept() and do something with the client socket ...
}
if (FD_ISSET(udpSock, &readSockSet))
{
printf("UDP Client query incoming...\n");
// call recv()/read() to read the datagram ...
}
// check connected TCP clients, if needed...
}
else if (retval < 0)
{
// check errno/WSAGetLastError(), call perror(), etc ...
}
}
Run Code Online (Sandbox Code Playgroud)