c - 了解用于接收 UDP 消息和打开 TCP 套接字的 Select 循环

标签 c sockets networking tcp udp

您好,我正在为一个网络类工作一个项目,我们在网络中创建节点,这些节点通过 udp 从控制应用程序接收消息,然后与其他节点创建 tcp 连接。基本顺序为: 1) 控制管理器向节点 A 发送 udp 消息,告知其连接到节点 B 2) 节点 A 接收 udp 消息并将该 udp 消息转发给节点 B 3) 节点 B 接收 udp 消息,随机选择一个端口号,在该端口上打开一个监听 tcp 套接字,并将 udp 消息发送回带有端口号的 A 4) 节点 A 收到 udp 消息并在该 tcp 端口上打开与节点 B 的连接。

基本上,我想循环接收到的 udp 消息并跳转到我的消息解析函数,同时循环 tcp 连接。这部分看起来很简单,但我真的不明白如何将监听套接字添加到文件描述符列表中。以下代码是我组合在一起的,我想知道基本结构是否正确?我不太明白如何创建监听tcp套接字并将其添加到fd列表中?

SOCKET udpsock;
udpsock = initudp(port); //setup udp socket
SOCKET tcpsock;
FD_ZERO(&rdsocks);

max = udpsock + 1;
while(1)
{
    SOCKET temp;

    FD_SET(udpsock,&rdsocks);//setup udp macros
    FD_SET(tcpsock,&rdsocks);

    if( select(max,&rdsocks,NULL,NULL,NULL) == SOCKET_ERROR )
    {
        perror("Select error");
        WSACleanup();
        return 1;
    }
    for(temp = 0; temp<=max;temp++) // loop on TCP sockets
    {
        if(FD_ISSET(temp,&rdsocks))
        {
            printf("Socket %d is ready \n",temp);
            // process tcp messages
        }

    }
    if(FD_ISSET(udpsock,&rdsocks)) // udp connection, parse control message
    {
        int ret = 0;
        res = recvfrom(udpsock, buff,sizeof(buff),0,(struct sockaddr*)&udpclient,lenaddr);
        //process udp message, setup tcp connection here if requested and add to file descriptor list?
    }

}

最佳答案

创建监听 TCP 套接字( socket(2) bind(2) listen(2) )后,使用 setsockopt(2) 将其标记为非阻塞。 ,并将其添加到 select(2) 的读取集中.

当它变为“可读”时,表示您有客户端连接待处理,请调用 accept(2) 。将新连接的套接字也添加到读取集中。

您可能想要保留这些客户端套接字的列表/哈希/任何内容,因为在每次调用 select(2) 之前必须重新初始化读取集并计算其第一个参数(最大 fd)。

注 0:我在这里引用了 Linux 手册页,但逻辑几乎是跨平台的。您可以在 MSDN 上找到 Windows 引用资料. 注1:Windows select() 忽略它的第一个参数。

关于c - 了解用于接收 UDP 消息和打开 TCP 套接字的 Select 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13731418/

相关文章:

c - Xcode 以外的其他 IDE 中的前缀 header

c - 如何仅用一个可迭代的矩阵相乘

c - 数组类型对于 struct iocb 具有不完整的元素类型

c - fork() 和 waitpid 可能的输出

c - 这个C多线程tcp服务器正确吗?

networking - Docker - 通过其公共(public) ip 访问同一台机器上的另一个容器,无需 docker 链接

c++ - 如何在不破坏数据的情况下将缓冲区转换为结构?

c# - 通过网络读取和解析大型文本文件的最佳方式是什么?

java - 为网络保留的位

java - Android - 同步线程与onSensorChanged发送udp数据包