为什么当我将POLLHUP添加为事件时,WSAPoll会返回错误(无效参数)?

问题描述 投票:0回答:1

我正在为我的项目使用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事件。

c winsock
1个回答
0
投票

根据WSAPoll()文档:

WSAEINVAL

传递了无效参数。如果fdarray参数包含NULL指针,则会返回此错误。如果在请求套接字状态时events参数指向的任何WSAPOLLFD结构的fdarray成员中指定了无效标志,则也会返回此错误。如果fd参数指向的任何WSAPOLLFD结构的fdarray成员中指定的套接字均无效,则也会返回此错误。

根据WSAPOLLFD文档:

events

类型:short

一组标志,指示所请求的状态类型。这必须是以下一项或多项。

POLLPRI 可以不受阻塞地读取优先级数据。 Microsoft Winsock提供程序不支持此标志。

POLLRDBAND 可以无阻塞地读取优先频段(带外)数据。

POLLRDNORM 可以不受阻塞地读取正常数据。

POLLWRNORM 可以不受阻塞地写入正常数据。

POLLIN标志被定义为POLLRDNORMPOLLRDBAND标志值的组合。 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被记录为reventsWSAPOLLFD成员的输出标志:

revents

类型:short

一组标志,在从WSAPoll函数调用返回时指示状态查询的结果。这可以是以下标志的组合。

...

POLLHUP 面向流的连接已断开连接或中止。

...

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

POLLHUP 挂断(仅在revents中返回;在events中忽略)。请注意,当从诸如管道或流套接字的通道读取时,此事件仅表示对等方关闭其通道的末尾。只有在消耗了通道中的所有未完成数据之后,来自通道的后续读取才会返回0(文件结束)。

所以,你不需要(在Windows上,你不能)明确请求POLLHUP,你只需要免费获得它。

© www.soinside.com 2019 - 2024. All rights reserved.