我正在为我的项目使用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
,你只需要免费获得它。