3

我正在尝试用 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 中写入,这意味着循环中的 Accept() 停止阻塞并且由于某种原因不会正确接受。我在网上读到这个错误是由于没有调用 WSAStartup() 引起的,但我确实在套接字的构造函数中调用了它,并且它确实在第一次接受了。

4

2 回答 2

12

10093 is WSANOTINITIALISED,这意味着要么WSAStartup()根本没有被调用,要么WSACleanup()被调用的次数比WSAStartup()被调用的次数多。

根据您提供的代码,似乎Socket::Accept()返回的是 aSocket而不是 a Socket*。如果是这样,那么Accept()正在创建一个在分配Socket后立即超出范围的临时Socket *socket对象。析构函数很可能在不应该Socket调用的时候调用。WSACleanup()呼叫WSAStartup()并且WSACleanup()必须始终保持平衡。

于 2013-05-10T08:35:50.883 回答
11

我在编写跨平台套接字应用程序时遇到了完全相同的问题。它在 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
于 2017-01-18T00:40:50.870 回答