如何在x时间后中止Winsock连接

时间:2015-04-24 13:23:57

标签: c++ c++11

我目前正在开发自己的TeamSpeak3Bot。对于连接部分,我使用的是Microsoft Winsock库。

建立连接如下所示:

// Initialize Winsock
WSAData winSockData;
WORD dllVersion = MAKEWORD(2, 1);
long iResult = WSAStartup(dllVersion, &winSockData);
if (iResult != NO_ERROR)
    return;

addrinfo* serverAddress = nullptr;
addrinfo* ptr = nullptr, hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;

iResult = getaddrinfo("127.0.0.1", "10011", &hints, &serverAddress);
if (iResult != 0)
    return;

// Create communication socket
SOCKET connectSocket = socket(AF_INET, SOCK_STREAM, /*IPPROTO_TCP*/0);
if (connectSocket == INVALID_SOCKET)
    return;

// Establish connection to server
iResult = connect(connectSocket, serverAddress->ai_addr (int)serverAddress->ai_addrlen);
if (iResult == SOCKET_ERROR)
    return;

// server address info not needed anymore
freeaddrinfo(serverAddress);

由于Winsock的send()recv()函数等待首先执行相应的发送/接收操作,因此主线程在此期间暂停。

如何正确检查recv()上的已接收输入?以及如何在特定时间(以毫秒为单位)后中止recv()

注意:如果send()recv()超时,我还需要能够抛出特定于类的异常!

2 个答案:

答案 0 :(得分:3)

您应该使用select()等待输入变为可用。这允许您指定超时。当select()告诉您套接字上的输入可用时,您可以使用recv()来读取它。

答案 1 :(得分:3)

一种可能性是使用非阻塞套接字然后你可以轮询。

您可以通过执行以下操作将套接字设置为非阻塞:

ULONG mode = 1;
int res = ioctlsocket(socket, FIONBIO, &mode);

这意味着如果那里没有任何内容,那么对recv的调用会立即返回并返回WSAGetLastError() WSAEWOULDBLOCK