我有给定的代码:
#include <winsock2.h> #include <sys/time.h> #include <iostream> int main() { WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { std::cout << "WSA Initialization failed!" << std::endl; WSACleanup(); } timeval time; time.tv_sec = 1; time.tv_usec = 0; int retval = select(0, NULL, NULL, NULL, &time); if (retval == SOCKET_ERROR) { std::cout << WSAGetLastError() << std::endl; } return 0; }它打印10022 ,这意味着错误WSAEINVAL。 根据这个页面 ,只有在以下情况下我才能得到这个错误:
WSAEINVAL:超时值无效,或者所有三个描述符参数均为空。
但是,我看到一些调用select()而没有任何FD_SET的例子。 以某种方式可能吗? 我需要在客户端代码中执行此操作,以使程序在未连接到服务器时短时间休眠。
I have the given code:
#include <winsock2.h> #include <sys/time.h> #include <iostream> int main() { WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { std::cout << "WSA Initialization failed!" << std::endl; WSACleanup(); } timeval time; time.tv_sec = 1; time.tv_usec = 0; int retval = select(0, NULL, NULL, NULL, &time); if (retval == SOCKET_ERROR) { std::cout << WSAGetLastError() << std::endl; } return 0; }It prints 10022, which means error WSAEINVAL. According to this page, I can get this error only if:
WSAEINVAL: The time-out value is not valid, or all three descriptor parameters were null.
However, I have seen a few examples calling select() without any FD_SETs. Is it possible somehow? I need to do it in a client-side code to let the program sleep for short periods while it is not connected to the server.
最满意答案
但是,我看到一些调用select()而没有任何FD_SET的例子。
它可以在大多数操作系统中使用(不是Windows)。
它可能以某种方式[在Windows下]?
不是直接的,但很容易在select()方式上打包自己的包装,即使在Windows下也可以提供所需的行为:
int proper_select(int largestFileDescriptorValuePlusOne, struct fd_set * readFS, struct fd_set * writeFS, struct fd_set * exceptFS, struct timeVal * timeout) { #ifdef _WIN32 // Note that you *do* need to pass in the correct value // for (largestFileDescriptorValuePlusOne) for this wrapper // to work; Windows programmers sometimes just pass in a dummy value, // because the current Windows implementation of select() ignores the // parameter, but that's a portability-killing hack and wrong, // so don't do it! if ((largestFileDescriptorValuePlusOne <= 0)&&(timeout != NULL)) { // Windows select() will error out on a timeout-only call, so call Sleep() instead. Sleep(((timeout->tv_sec*1000000)+timeout->tv_usec)/1000); return 0; } #endif // in all other cases we just pass through to the normal select() call return select(maxFD, readFS, writeFS, exceptFS, timeout); }...然后只需调用proper_select()而不是select(),你就是金。
However, I have seen a few examples calling select() without any FD_SETs.
It will work in most OS's (that aren't Windows).
Is it possible somehow [under Windows]?
Not directly, but it's easy enough to roll your own wrapper around select() that gives you the behavior you want even under Windows:
int proper_select(int largestFileDescriptorValuePlusOne, struct fd_set * readFS, struct fd_set * writeFS, struct fd_set * exceptFS, struct timeVal * timeout) { #ifdef _WIN32 // Note that you *do* need to pass in the correct value // for (largestFileDescriptorValuePlusOne) for this wrapper // to work; Windows programmers sometimes just pass in a dummy value, // because the current Windows implementation of select() ignores the // parameter, but that's a portability-killing hack and wrong, // so don't do it! if ((largestFileDescriptorValuePlusOne <= 0)&&(timeout != NULL)) { // Windows select() will error out on a timeout-only call, so call Sleep() instead. Sleep(((timeout->tv_sec*1000000)+timeout->tv_usec)/1000); return 0; } #endif // in all other cases we just pass through to the normal select() call return select(maxFD, readFS, writeFS, exceptFS, timeout); }... then just call proper_select() instead of select() and you're golden.
更多推荐
发布评论