C ++中的TCP服务器套接字打开失败

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C ++中的TCP服务器套接字打开失败相关的知识,希望对你有一定的参考价值。

我目前正在创建一个程序,我需要TCP服务器与android应用程序进行通信。我已经编写并测试了TCP服务器作为一个单独的项目,它运行完全正常。当把它包含在一个更大的项目中时,我有其他进程,它不再打开套接字进行监听。

我的项目是在Visual Studio 2017中创建的,我使用的库是:

  • TCP的WS2_32.lib
  • OpenCV用于图像处理
  • Libcurl用于将文件发送到数据库
  • ACTi SDK用于从相机中提取图像

我写的TCP服务器代码是(取自https://www.youtube.com/watch?v=WDn-htpBlnU&t=162s):

void TCPServer()
{
    //Initalize winsock
    WSADATA wsData;
    WORD ver = MAKEWORD(2, 2);

    int wsOk = WSAStartup(ver, &wsData);
    if (wsOk != 0)
    {
        cerr << "Can't init winsock" << endl;
        return;
    }

    //Create a socket
    SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
    if (listening == INVALID_SOCKET)
    {
        cerr << "Can't create socket" << endl;
        return;
    }

    //Bind the socket to an ip address and port
    sockaddr_in hint;
    hint.sin_family = AF_INET;
    hint.sin_port = htons(100);
    hint.sin_addr.S_un.S_addr = INADDR_ANY; //Could use inet_pton()

    bind(listening, (sockaddr*)&hint, sizeof(hint));

    //Tell Winsock the socket is for listening 
    listen(listening, SOMAXCONN);

    //Wait for a connection
    sockaddr_in client;
    int clientSize = sizeof(client);

    SOCKET clientsocket = accept(listening, (sockaddr*)&client, &clientSize);

    char host[NI_MAXHOST];  //Clients remote name
    char service[NI_MAXHOST];   //Service the client is on

    ZeroMemory(host, NI_MAXHOST);
    ZeroMemory(service, NI_MAXHOST);

    if (getnameinfo((sockaddr*)&client, sizeof(client), host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0)
    {
        cout << host << "connected on port " << service << endl;
    }
    else {
        inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
        cout << host << " connected on port " << ntohs(client.sin_port) << endl;
    }

    //Close listening socket
    closesocket(listening);

    //While loop:accept and echo message back to client
    char buf[4096];

    while (true)
    {
        ZeroMemory(buf, 4096);

        //Wait for client to send data
        int bytesReceived = recv(clientsocket, buf, 4096, 0);
        if (bytesReceived == SOCKET_ERROR)
        {
            cerr << "Error in recv()" << endl;
            break;
        }

        if (bytesReceived == 0)
        {
            cout << "Client disconnected" << endl;
            break;
        }

        cout << buf << endl;
    }

    //Close the socket
    closesocket(clientsocket);

    //cleanup windsock
    WSACleanup();
}

正如我所说,这段代码作为一个单独的项目工作,但是当我将它包含在我的整个项目中时,套接字无法打开,并且立即建立了与204.204.204.204的连接。通过使用netstat查看所有打开的套接字,在两种情况下都检查了这一点。我觉得这可能是一个库冲突,可能在WS2_32和libcurl之间,但我不确定。

我目前正在通过在我的主程序中调用TCPServer()来测试它,但是我计划将服务器与其他进程一起运行。

关于套接字可能无法打开的任何建议将非常感激。

答案

在对功能进行检查后,可以将故障缩小到bind(...)功能。似乎错误归结为using namespace std;

解决方案是通过执行::bind(...)从全局命名空间调用bind。这个解决方案在这里找到:Compilation errors with socket bind function

以上是关于C ++中的TCP服务器套接字打开失败的主要内容,如果未能解决你的问题,请参考以下文章

C语言中的fopen函数的具体实现是怎么样?

C 中的共享内存代码片段

NFS 文件在 C 代码中打开

使用system(命令)时,AWS中的C ++代码失败并显示错误“无法分配内存”

C语言扫雷小游戏的实现(附详细代码)

如何优化C ++代码的以下片段 - 卷中的零交叉