C:使用Select监听两个socket

标签 c sockets select server

我正在编写一个连接到多个客户端的服务器。目前,我在 SOCK_STREAM 套接字上使用 accept 来连接新客户端。我希望能够接受来自将数据报发送到服务器的 SOCK_DGRAM 套接字的客户端的查询。由于接受只是挂起,直到客户端发送连接到该套接字的请求,我需要一种方法来监视两个套接字,直到一个接收到来自客户端的请求,然后才能处理该请求并返回监视套接字。我不需要立即处理请求(即,如果客户端在另一个客户端请求连接后发送查询,则查询客户端将不得不等待服务器完成连接客户端的请求,反之亦然)。我知道套接字可以提醒服务器有多少套接字准备读/写,但它如何告诉服务器哪个套接字准备好了? IE。哪个套接字准备好读取,哪个准备好写入?这是我的尝试,我知道监听器在连接后总是需要写入,而 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");
        }
    }

最佳答案

不是在 accept() 上阻塞,而是使用 select() 来告诉您客户端何时挂起,这样您就可以调用 accept() 没有阻塞。然后就可以同时监控TCP和UDP套接字了。您拥有的代码已经在正确的轨道上完成该任务,但是您正在使用 writing fdset 来检测何时调用 accept() 而您应该使用读取 fdset,并且您不会在每次循环迭代时重置 fdset 或超时,因为 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 ...
    }
}

关于C:使用Select监听两个socket,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29358443/

相关文章:

c - 如何确定结构成员的大小?

c - ftruncate 无法与 msys2 一起正常工作

Core Graphics 函数/C 为什么被调用的函数填充发送的数组?

python - 我无法将 GUI 合并到我的 python 程序中

Angularjs 选择值未定义

java - 选择该表中的任何行后,如何使 JTable 行变为 "unselected"状态?

mysql - 更新并显示 mysql 查询

c++ - 什么是 16 字节有符号整数数据类型?”

android - java.net.ServerSocket.accept () 在 Android 上不返回

Java:通过套接字发送后公钥不同