2

我正在尝试创建一个事件驱动的多线程 UDP/DTLS 服务器。设计基于以下概念

  1. 有一个客户端连接的 UDP 套接字
  2. 使用 Epoll 请求 UDP 侦听套接字上的事件。
  3. UDP 套接字充当 TCP 侦听套接字并创建连接到特定客户端的子 fd。为此,我为我的对象实现了一个 UDPAccept 方法,该方法具有如下所示的伪代码

    UDPAccept(int fd,struct sockaddr * addr,
       socklen_t * addr_len,void *sockBuf,size_t *read)
    {
        //sanity checks
        int childfd = -1;
        int error = 1;
        socklen_t localLen,peerLen;
        int family;
        struct sockaddr_in         local4,peer4;
        struct sockaddr            temp;
        size_t maxLen = 65535;
        getsockname(fd,(struct sockaddr *)&temp,&localLen);
        family = temp.sa_family;
        do
        {
         childfd = socket(family,SOCK_DGRAM,0);
         //error handling       
         //handle IPV6 
         local4 = (sockaddr_in *)temp;
         error = recvfrom( fd, sockBuf,
                            maxLen,0,(struct sockaddr *)&peer4,
                                             &peerLen);
         error = bind(childfd,(struct sockaddr *)&local4,sizeof local4);
         error = connect(childfd,(struct sockaddr *)&peerV4,peerLen);
        //handle error      
       }while(0);
       if(addr != NULL && addr_len != NULL)
       {
        *addr_len = peerLen;
        addr = &peerV4;
        *read = error;
       }    
       // error handling and cleanup
       return childfd;
    }
    
  4. 将子套接字添加到 Epoll 表。

    epoll_ctl(efd,EPOLL_CTL_ADD,newFd,&event);
    
  5. 轮询子事件并监听套接字

    currentSize = epoll_wait(efd,events,MAX_SOCKET_FD,timeout);
    //handle errors
    for(i = 0; i < currentSize;i++)
    {
    
        if(events[i].data.fd == listenUDP)
            //call UDPAccept
            // update local tables
       else
            //handle child fd events
    }
    
  6. 对同一事物有多个线程,在接受期间使用锁同步

现在我的问题是 epoll 会停止在侦听套接字上给我 POLLIN 事件,因为我已经为客户端创建了一个新的 UDP 子连接套接字,还是我必须自己处理它

4

2 回答 2

4

除非您从events.

但我想知道你为什么要这样做。您可以对所有内容使用单个 UDP 套接字。这要简单得多。

于 2015-01-15T22:48:47.220 回答
0

根据 connect() 上的 Linux 手册页,过滤器将确保只有来自“已连接”对等方的数据报才会传送到新套接字。

不过有一个警告...... bind() 调用将暂时接管侦听器的端口,直到连接调用()。这是一个小窗口,但可能导致来自其他客户端的数据报出现在“已连接”套接字上。您可以通过验证对等地址来忽略它们。

于 2019-01-12T15:36:35.910 回答