我正在为我的项目使用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标志定义为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,您只需免费获得它即可。

10-01 03:09