C++ Winsock 10093错误

lp0sw83n  于 2023-01-06  发布在  其他
关注(0)|答案(2)|浏览(287)

我尝试用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引起的(),但我确实在套接字的构造函数中调用了它,它确实在第一次接受了。

rpppsulh

rpppsulh1#

10093是WSANOTINITIALISED,这意味着:

  • 套接字调用在WSAStartup()被调用之前就被进行。
  • 套接字调用是在调用WSACleanup()的次数与调用WSAStartup()的次数一样多之后进行的。

根据您提供的代码,Socket::Accept()似乎是按值返回Socket对象,而不是Socket*指针。如果是这样,则Accept()正在创建临时Socket,该临时SocketSocket *socket被赋值后立即超出作用域。很有可能Socket析构函数在不应该调用WSACleanup()时调用了它。对WSAStartup()WSACleanup()的调用必须始终保持平衡。
调用WSAStartup()的最佳时机是在程序启动时,而不是在对象的构造函数中;同样,调用WSACleanup()的最佳时机是在退出前的程序清理时,而不是在对象的析构函数中。

zf9nrax1

zf9nrax12#

我在编写一个跨平台套接字应用程序时遇到了同样的问题。它在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

相关问题