为什么当我添加 POLLHUP 作为事件时,WSAPoll returns 错误(无效参数)?

Why when I add POLLHUP as event, WSAPoll returns error (invalid arguments)?

我正在为我的项目使用 WSAPoll。我使用跟踪 POLLIN 和 POLLOUT 事件。一切都很好。当我将 POLLHUP 添加为事件时,WSAPoll returns 错误 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

An invalid parameter was passed. This error is returned if the fdarray parameter contains a NULL pointer. This error is also returned if invalid flags were specified in the events member of any of the WSAPOLLFD structures pointed to by the fdarray parameter when requesting socket status. This error is also returned if none of the sockets specified in the fd member of any of the WSAPOLLFD structures pointed to by the fdarray parameter were valid.

根据 WSAPOLLFD 文档:

events

Type: short

A set of flags indicating the type of status being requested. This must be one or more of the following.

POLLPRI
Priority data may be read without blocking. This flag is not supported by the Microsoft Winsock provider.

POLLRDBAND
Priority band (out-of-band) data can be read without blocking.

POLLRDNORM
Normal data can be read without blocking.

POLLWRNORM
Normal data can be written without blocking.

The POLLIN flag is defined as the combination of the POLLRDNORM and POLLRDBAND flag values. The POLLOUT flag is defined as the same as the POLLWRNORM flag value.

因此,如您所见,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
然而,

POLLHUPWSAPOLLFDrevents 成员中记录为 output 标志:

revents

Type: short

A set of flags that indicate, upon return from the WSAPoll function call, the results of the status query. This can a combination of the following flags.

...

POLLHUP
A stream-oriented connection was either disconnected or aborted.

...

这与 *nix 平台上 poll()POLLHUP 的使用相匹配:

POLLHUP
Hang up (only returned in revents; ignored in events). Note that when reading from a channel such as a pipe or a stream socket, this event merely indicates that the peer closed its end of the channel. Subsequent reads from the channel will return 0 (end of file) only after all outstanding data in the channel has been consumed.

因此,您不需要(并且在 Windows 上,您不能)明确请求 POLLHUP,您可以免费获得它。