我尝试用C++建立一个服务器,它可以接受多个客户端。为此,我建立了一个winsock Package 器,并使用线程与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++;
}
现在,第一个客户端接受fine和WSAGetLastError()返回0,但在第一个连接后,即使我不尝试连接另一个,它也会继续在控制台10093中写入,这意味着接受循环中的()停止了阻塞,并且由于某种原因无法正确接受。我在网上读到这个错误是由于没有调用WSAStartup引起的(),但我确实在套接字的构造函数中调用了它,它确实在第一次接受了。
2条答案
按热度按时间rpppsulh1#
10093是
WSANOTINITIALISED
,这意味着:WSAStartup()
被调用之前就被进行。WSACleanup()
的次数与调用WSAStartup()
的次数一样多之后进行的。根据您提供的代码,
Socket::Accept()
似乎是按值返回Socket
对象,而不是Socket*
指针。如果是这样,则Accept()
正在创建临时Socket
,该临时Socket
在Socket *socket
被赋值后立即超出作用域。很有可能Socket
析构函数在不应该调用WSACleanup()
时调用了它。对WSAStartup()
和WSACleanup()
的调用必须始终保持平衡。调用
WSAStartup()
的最佳时机是在程序启动时,而不是在对象的构造函数中;同样,调用WSACleanup()
的最佳时机是在退出前的程序清理时,而不是在对象的析构函数中。zf9nrax12#
我在编写一个跨平台套接字应用程序时遇到了同样的问题。它在Linux和OS X上运行良好,但在Windows上出现了错误10093。要解决这个问题,请在调用任何Winsock函数之前添加以下代码: