Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Winsock-等待并调用accept(),直到客户端真正尝试连接 我用Winsock API在C++中创建一个服务器。我想知道是否只有在某些连接实际出现时才有可能调用accept()函数,这样我就不必阻塞accept()上的线程。换句话说,我想让我的线程等待并仅在客户端尝试连接时调用accept()函数。这可能吗?_C++_Winsock2 - Fatal编程技术网

Winsock-等待并调用accept(),直到客户端真正尝试连接 我用Winsock API在C++中创建一个服务器。我想知道是否只有在某些连接实际出现时才有可能调用accept()函数,这样我就不必阻塞accept()上的线程。换句话说,我想让我的线程等待并仅在客户端尝试连接时调用accept()函数。这可能吗?

Winsock-等待并调用accept(),直到客户端真正尝试连接 我用Winsock API在C++中创建一个服务器。我想知道是否只有在某些连接实际出现时才有可能调用accept()函数,这样我就不必阻塞accept()上的线程。换句话说,我想让我的线程等待并仅在客户端尝试连接时调用accept()函数。这可能吗?,c++,winsock2,C++,Winsock2,当您使用Winsock时,可以使用Microsoft特定的扩展功能AcceptEx。这允许您以“重叠I/O”的形式执行接受,这在概念上意味着接受在后台运行,您偶尔可以通过检查OverlappedResult,或通过对OverlappedHandle执行等待来检查它是否发生AcceptEx还可以选择执行第一次接收 在不编写所有代码并对其进行彻底测试的情况下,类似以下内容应该可以工作: // The following: // Has no error checking // Assumes

当您使用Winsock时,可以使用Microsoft特定的扩展功能
AcceptEx
。这允许您以“重叠I/O”的形式执行接受,这在概念上意味着接受在后台运行,您偶尔可以通过检查
OverlappedResult
,或通过对OverlappedHandle执行等待来检查它是否发生
AcceptEx
还可以选择执行第一次接收

在不编写所有代码并对其进行彻底测试的情况下,类似以下内容应该可以工作:

// The following:
//   Has no error checking
//   Assumes sListen is a bound listening socket
//   Some other assumptions I've not listed :)

// Allocate space to store the two sockaddr's that AcceptEx will give you
// 
char lpOutputBuffer[sizeof((sockaddr_in)+16) * 2];

SOCKET sAccept = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
WSAOVERLAPPED olOverlap;

ZeroMemory(&olOverlap, sizeof(WSAOVERLAPPED));
olOverlap.hEvent = WSACreateEvent();

DWORD dwBytes;

BOOL bAcceptRet =
    AcceptEx(sListen, // the listen socket
             sAccept, // the socket to use for the accepted connection
             lpOutputBuffer, // where to store the received information
             0, // don't do a receive, just store the local and remote addresses
             sizeof((sockaddr_in)+16), // size of the local address area
             sizeof((sockaddr_in)+16), // size of the remote address area
             &dwBytes, // set to received bytes if we complete synchronously
             &olOverlap); // our overlapped structure

if (bAcceptRet) {
    // the function completed synchronously.
    // lpOutputBuffer should contain the address information.
    // sAccept should be a connected socket
} else {
    // the function didn't complete synchronously, so is the accept Pending?
    if (ERROR_IO_PENDING == WSAGetLastError()) {
        // in this case, our Accept hasn't happened yet...
        // later in our code we can do the following to check if an accept has occurred:
        // note that the FALSE tells WSAGetOverlappedResult not to wait for the I/O to complete
        // it should return immediately
        ...
        DWORD dwFlags;
        if (WSAGetOverlappedResult(sListen, &olOverlap, &dwBytes, FALSE, &dwFlags)) {
            // the accept has succeeded, so do whatever we need to do with sAccept.
        }
        ...
    }
}
当然,这是一个非常快速的、经过黑客攻击的、可能不工作、不可编译的代码,但它应该让您知道如何做类似于您想要做的事情,以及在哪里查找

顺便提一下,在技术上没有必要设置
wsaooverlapped
结构的
hEvent
参数,但这样做允许您实际等待请求完成:

if (WAIT_OBJECT_0 == WaitForSingleObject(olOverlap.hEvent, INFINITE)) {
    // The accept occurred, so do something with it
}

现在,我将等待有人指出我代码中的巨大错误…

使用select()告诉accept()何时不会阻塞。或者在异步模式下使用套接字。使用
WSAAsyncEvent()
WSAAsyncSelect()
让Winsock在新连接挂起时通知您。