使用poll()的多端口监听UDP服务器仅能接收单端口报文求助
问题诱因分析
以下是导致你仅能监听单个端口及其他潜在异常的所有核心原因:
- 核心错误:poll系统调用参数错误
你代码中的pfd是动态申请的堆内存指针,sizeof(pfd)获取的是指针本身的大小(32位系统为4字节,64位系统为8字节),而非数组总长度,因此sizeof(pfd) / sizeof(pfd[0])的计算结果恒为1(64位下struct pollfd大小为8字节,刚好8/8=1),导致poll仅监听第一个文件描述符,也就是第一个绑定的端口,这是你只能监听单个端口的直接原因。
正确写法应该将poll的第二个参数替换为提前计算好的端口总数AmountOfPorts:
int ev_cnt = poll(pfd, AmountOfPorts, 100000);
- 未定义变量错误
recvfrom的返回值没有赋值给rcv变量,代码中直接判断if (rcv > 0),rcv属于未初始化的野变量,会导致接收逻辑判断异常。正确写法:
ssize_t rcv = recvfrom(s[i], buffer, sizeof(buffer), 0, (struct sockaddr *)(&addr[i]), &addrlen);
- POLLOUT事件处理逻辑错误
- 初始注册
POLLIN | POLLOUT事件不合理:UDP套接字只要发送缓冲区有空余就会一直触发POLLOUT事件,会导致poll立刻返回,CPU占用率100%,仅当有待发送数据时才需要注册POLLOUT事件,发送完成后取消注册即可。 - POLLOUT的判断逻辑被包裹在POLLIN的判断分支内,只有当前套接字有读事件时才会处理写事件,逻辑完全错误,应该将POLLOUT的判断和POLLIN的判断平级。
- POLLOUT处理逻辑中取客户端IP时使用了
*addr,没有指定下标i,会一直取第一个端口的地址结构体内容,逻辑错误。
- 客户端链表逻辑错误
search函数新增节点时没有正确修改头指针,当head初始为NULL时,新增的客户端节点无法挂载到全局链表上,链表功能完全失效。 - 其他潜在问题
UDP是无连接协议,POLLHUP事件对UDP套接字无意义,不需要处理;非阻塞模式下的recvfrom和sendto需要处理EAGAIN/EWOULDBLOCK错误,避免异常退出。
内容的提问来源于stack exchange,提问作者Ilya
相关产品推荐
相关产品推荐

