gpt4 book ai didi

c++ - Winsock - 等待调用 accept() 直到客户端真正尝试连接

转载 作者:太空宇宙 更新时间:2023-11-04 14:05:50 25 4
gpt4 key购买 nike

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

最佳答案

当您使用 Winsock 时,您可以使用 Microsoft 特定的扩展函数 AcceptEx。这允许您将接受作为“重叠 I/O”执行,这在概念上意味着接受在后台运行,您可以偶尔进入并检查它是否发生,方法是检查 OverlappedResult,或者通过在 OverlappedHandle 上执行 Wait。 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.
}
...
}
}

当然,这是一段非常快速的、拼凑而成的代码,可能无法正常工作、不可编译,但它应该让您了解如何做与您想要的类似的事情,以及在哪里查看。

顺便说一句,从技术上讲,设置 WSAOVERLAPPED 结构的 hEvent 参数不是必需的,但这样做可以让您实际上等待要求完成:

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

我现在将等待有人指出我代码中的巨大明显错误...

关于c++ - Winsock - 等待调用 accept() 直到客户端真正尝试连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16999503/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com