WSAPoll 更改 FDSET 中的数据并由于 WSAENOTSOCK 返回错误。我是否正确使用了 WSAPoll()?

WSAPoll changing data in FDSET and returning an error due to WSAENOTSOCK. Am I using WSAPoll() correctly?

以下是使用 WSAPoll 所需的最少代码,不包括初始化(socket()bind()listen()accept() 等)或任何条件在它之前。您可以使用文档中的 sample server codesockClientSocket 作为基础。

运行 它,每行的值变化如下:

// ...
// socket(), bind(), listen(), etc.
// sock = accept(...)
// See boilerplate linked.

SOCKET sock;          // sock = 356
FDSET set;            // Some garbled data, though should be same as below:
FD_ZERO(&set);        // fd_count = 0, fd_array = [14757395258967641292, x64]
FD_SET(sock, &set);   // fd_count = 1, fd_array = [356, 14757395258967641292 x63]
int iResult = WSAPoll(&set, 1, 1)      // iResult = -1
                      // fd_count = 1, fd_array = [262500, 14757395258967641292 x63]
int errid = WSAGetLastError();    // errid = WSAENOTSOCK (10038)

// if (iResult > 0)
// recv(), etc.

如果我没看错,WSAPoll() is supposed to emulate poll()。因此,当我将 sock 存储到 set 时,它会正确存储它,但是当它被传递到 WSAPoll() 时,值会发生变化并且它 returns -1 与 errnoWSAENOTSOCK (10038).

现在,这里的问题是 sock 是一个完全有效的文件描述符;插座。 recv()send() 工作正常,没有任何错误。
另一方面,文件描述符 262500,没那么多。

我是在正确地轮询还是在某种程度上没有正确地转换它,因为它看起来不需要转换,因为 SOCKETfd_array 只是 a/an singular/array,共 unsigned __int64(s)。

您混淆了 select()poll()/WSAPoll() 的参数。

它是select(),它以一个FDSET作为参数。 poll()/WSApoll() 接受一个 pollfd 数组作为参数。

所引用的 Microsoft 文档中用于描述 WSAPOLLFD 参数的超链接似乎符合 404 标准。也许您可以在其他地方找到它,或者使用 Linux 版本的文档,(Google 关键字:struct pollfd)。

您的编译器也很有可能向您发出警告信息和其他脏话;因为 WSAPoll 的第一个参数的类型显然是错误的指针类型。如果是这样,这是一个很好的教训,永远不要忽略来自 C++ 编译器的警告消息,即使它仍在编译您的程序。