我正在尝试用C ++构建一个可以接受多个客户端的服务器。为此,我构建了一个winsock包装器,并为每个客户端使用带有boost的线程进行通信 在尝试接受客户端时遇到了一个奇怪的问题,我有一个看起来像这样的循环。
int clientID = 0;
listenSocket = new Socket(SocketType::TCP);
listenSocket->Bind(port);
listenSocket->Listen();
while(running)
{
Socket *socket = &listenSocket->Accept();
mutex.lock();
clients.push_back(new Client(socket, clientID));
mutex.unlock();
std::cout << "Client with id " << clientID << " connected!" << std::endl;
std::cout << WSAGetLastError() << std::endl;
clientID++;
}
现在,第一个客户端接受罚款,WSAGetLastError()返回0,但是在第一个连接后,即使我不尝试连接另一个,它只是继续写入控制台10093,这意味着接受()循环停止阻塞,由于某种原因不能正确接受。我在网上看到这个错误是由于没有调用WSAStartup()引起的,但是我确实在套接字的构造函数中调用了它,它确实在第一次接受了。
答案 0 :(得分:10)
10093是WSANOTINITIALISED
,这意味着WSACleanup()
被调用次数超过WSAStartup()
。
根据您提供的代码,Socket::Accept()
似乎正在返回Socket
而不是Socket*
。如果是,那么Accept()
正在创建一个临时Socket
,该Socket *socket
在分配Socket
后立即超出范围。有可能WSACleanup()
析构函数在不应该调用WSAStartup()
时调用WSACleanup()
。必须始终平衡对{{1}}和{{1}}的呼叫。
答案 1 :(得分:5)
在编写跨平台套接字应用程序时,我遇到了完全相同的问题。它在Linux和OS X上工作正常,但我在Windows上收到此错误10093。要修复它,在调用任何winsock函数之前添加此代码:
#ifdef WIN32
// Initialize Winsock
int iResult;
WSADATA wsaData;
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
std::cout << "WSAStartup failed: " << iResult << std::endl;
return;
}
#endif