我正在为我的项目使用WSAPoll。我使用了跟踪POLLIN和POLLOUT事件。一切都很好。当我将POLLHUP添加为事件时,WSAPoll返回错误10022(无效参数)。
我不知道怎么了,请指导我如何解决:(cc_qnt
-连接的客户端数量
int ev_cnt = WSAPoll(pfd, cc_qnt + 1, 100);
if (ev_cnt > 0) {
for (i = 0; i < cc_qnt; i++) {
if (pfd[i].revents & POLLHUP) {
// some code
}
if (pfd[i].revents & POLLIN) {
// some code
}
}
if (pfd[cc_qnt].revents & POLLIN) {
在这一部分中,我们准备接受新的连接。我们编辑
pfd[cc_qnt]
添加新的套接字(由accept返回),而不是监听套接字。然后,我们以大小+ 1重新分配pfd,复制先前的数据,并在cc数组的末尾添加侦听套接字。 int addrlen = sizeof(addr);
cc[cc_qnt].s = accept(ls, (struct sockaddr*) &addr, &addrlen);
cc[cc_qnt].ip = ntohl(addr.sin_addr.s_addr);
cc[cc_qnt].sent_put = 0;
cc[cc_qnt].c_cl_cn = 0;
pfd[cc_qnt].fd = cc[i].s;
pfd[cc_qnt].events = POLLIN | POLLOUT | POLLHUP;
cc_qnt++;
pfd = init_pfd(pfd, ls, cc_qnt);
}
}
else if (ev_cnt < 0) {
exit(printf("\nprocess_events: WSAPoll, ev_cnt = %d, WSAGetLastError: %d \n", ev_cnt, WSAGetLastError()));
}
我为跟踪POLLHUP而更改的所有内容-将其添加到pfd [cc_qnt] .events中,WSAPoll开始返回错误。我希望跟踪POLLHUP事件。
最佳答案
根据WSAPoll()
文档:
WSAEINVAL
传递了无效的参数。如果fdarray
参数包含NULL
指针,则返回此错误。如果在请求套接字状态时,在events
参数所指向的任何WSAPOLLFD
结构的fdarray
成员中指定了无效标志,也会返回此错误。如果fd
参数所指向的任何WSAPOLLFD
结构的fdarray
成员中指定的所有套接字均无效,则也会返回此错误。
并根据WSAPOLLFD
文档:
events
类型:short
一组标志,指示请求的状态类型。这必须是以下一项或多项。
POLLPRI
可以读取优先数据而不会阻塞。 Microsoft Winsock提供程序不支持此标志。
POLLRDBAND
可以读取优先带(带外)数据而不会阻塞。
POLLRDNORM
可以读取普通数据而不会阻塞。
POLLWRNORM
可以写入普通数据而不会阻塞。
POLLIN
标志定义为POLLRDNORM
和POLLRDBAND
标志值的组合。 POLLOUT
标志的定义与POLLWRNORM
标志的值相同。
因此,如您所见,POLLHUP
未被记录为有效输入WSAPoll()
的标志。实际上,它与winsock2.h
中定义的任何上述标志都不匹配:
/* Event flag definitions for WSAPoll(). */
#define POLLRDNORM 0x0100
#define POLLRDBAND 0x0200
#define POLLIN (POLLRDNORM | POLLRDBAND)
#define POLLPRI 0x0400
#define POLLWRNORM 0x0010
#define POLLOUT (POLLWRNORM)
#define POLLWRBAND 0x0020
#define POLLERR 0x0001
#define POLLHUP 0x0002
#define POLLNVAL 0x0004
但是,
POLLHUP
被记录为revents
的WSAPOLLFD
成员中的输出标志:revents
类型:
short
一组标志,用于指示从WSAPoll函数调用返回后的状态查询结果。这可以是以下标志的组合。
...
POLLHUP
面向流的连接已断开或中止。
...
这与* nix平台上
POLLHUP
中poll()
的使用相匹配:POLLHUP
挂断电话(仅在
revents
中返回;在events
中忽略)。注意从管道或溪流等通道读取时
套接字,此事件仅表明对等方已关闭其
频道的结尾。随后从通道读取
仅在所有未完成的数据之后,才返回0(文件末尾)
频道已被使用。
因此,您不需要(在Windows上也不能)显式请求
POLLHUP
,您只需免费获得它即可。