我目前正在开发自己的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()
超时,我还需要能够抛出特定于类的异常!
答案 0 :(得分:3)
您应该使用select()
等待输入变为可用。这允许您指定超时。当select()
告诉您套接字上的输入可用时,您可以使用recv()
来读取它。
答案 1 :(得分:3)
一种可能性是使用非阻塞套接字然后你可以轮询。
您可以通过执行以下操作将套接字设置为非阻塞:
ULONG mode = 1;
int res = ioctlsocket(socket, FIONBIO, &mode);
这意味着如果那里没有任何内容,那么对recv的调用会立即返回并返回WSAGetLastError()
WSAEWOULDBLOCK
。