首页 文章

Epoll是否可以使用UDP侦听套接字来使用事件驱动的UDP服务器

提问于
浏览
2

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

  • 具有客户端连接的UDP套接字

  • 使用Epoll询问UDP侦听套接字上的事件 .

  • UDP套接字充当TCP侦听套接字并创建连接到特定客户端的子fds . 为此,我为我的对象实现了一个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;
}
  • 将子套接字添加到Epoll表 .
epoll_ctl(efd,EPOLL_CTL_ADD,newFd,&event);
  • 轮询子节点和侦听套接字上的事件
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
}
  • 有多个线程同一个东西,在接受期间使用锁同步

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

2 回答

  • 0

    除非从 events 删除第一个套接字,否则它将在两个套接字上传递事件 .

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

  • 2

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

    但有一点需要注意...... bind()调用将简单地从侦听器接管端口,直到connect call() . 这是一个小窗口,但可能导致其他客户端的数据报出现在“已连接”的套接字上 . 您可以通过验证对等地址来忽略它们 .

相关问题