简体   繁体   English

c++ TCP 客户端和服务器无法在本地计算机上通信

[英]c++ TCP client and server not able to communicate on local machine

I have built a simple c++ TCP server and client using winsock.我使用winsock构建了一个简单的c++ TCP服务器和客户端。 The code all compiles without error however either the server is refusing connections or my client is failing to connect properly.代码全部编译没有错误,但是服务器拒绝连接或我的客户端无法正确连接。

The code is alot to put onto stackoverflow so here is a pastebin for the server and Client.代码很多放在stackoverflow上,所以这里是服务器和客户端的pastebin。

https://pastebin.com/ZQavPxsR - Server Code https://pastebin.com/ZQavPxsR - 服务器代码

https://pastebin.com/cLFVp2B1 - Client Code https://pastebin.com/cLFVp2B1 - 客户端代码

    sockaddr_in clientService;
    clientService.sin_family = AF_INET;
    InetPton(AF_INET, _T("127.0.0.1"), &clientService.sin_addr.s_addr);
    clientService.sin_port = htons(port);
 
    if (connect(clientSocket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR)
    {
        std::cout << "Client: connect() = Failed to connect." << std::endl;
        WSACleanup();
        system("pause");
        return 0;
    }
    else
    {
        std::cout << "Client: connect() is OK." << std::endl;
        std::cout << "Client: Can start sending and reciving data... " << std::endl;
    }

Above is a snippet of the code that is from the client and is responsible for making the connection with the server.上面是来自客户端的代码片段,负责与服务器建立连接。

    acceptSocket = accept(serverSocket, NULL, NULL);

    if (acceptSocket == INVALID_SOCKET)
    {
        std::cout << "Accept Failed: " << WSAGetLastError() << std::endl;
        WSACleanup();
        return -1;
    }
    else
    {
        std::cout << "Accepted connection " << std::endl;
        system("pause");
        WSACleanup();
    }

Above is a snippet of the code that is from the server and is responsible for accepting the connection with the client.上面是来自服务器的代码片段,负责接受与客户端的连接。

Your server is not initializing the service.sin_port field before calling bind() , so the code exhibits undefined behavior .您的服务器在调用bind()之前没有初始化service.sin_port字段,因此代码表现出未定义的行为 Your listening socket will end up trying to bind to whatever random port value was already present in the memory that the sin_port field occupies.您的侦听套接字最终将尝试绑定到sin_port字段占用的 memory 中已经存在的任何随机端口值。 And if that value happens to be 0 , then bind() will choose a random port from Windows' available ephemeral ports.如果该值恰好是0 ,则bind()将从 Windows 的可用临时端口中选择一个随机端口。 In any case, it is very unlikely that your server is ever going to be listening on port 4679 , which is the port the client is trying to connect to.在任何情况下,您的服务器都不太可能监听端口4679 ,这是客户端尝试连接的端口。


On a side note, there are some other problems with your code:附带说明一下,您的代码还有其他一些问题:

  • In both client and server, your calls to InetPton() should be passing in a pointer to the sockaddr_in::sin_addr field, not the sockaddr_in::sin_addr.s_addr field.在客户端和服务器中,您对InetPton()的调用应该传递一个指向sockaddr_in::sin_addr字段的指针,而不是sockaddr_in::sin_addr.s_addr字段。 It "works" only because s_addr is the sole data member of sin_addr and thus they have the same memory address.它“有效”只是因为s_addrsin_addr的唯一数据成员,因此它们具有相同的 memory 地址。 But technically, this is undefined behavior since InetPton() wants an IN_ADDR* not a ULONG* .但从技术上讲,这是未定义的行为,因为InetPton()想要一个IN_ADDR*而不是ULONG*

  • Your server is not exiting if listen() fails, is leaking serverSocket whether accept() succeeds or fails, and is leaking acceptSocket if accept() succeeds.如果listen()失败,您的服务器不会退出,无论accept()成功还是失败都会泄漏serverSocket ,如果accept()成功则泄漏acceptSocket

  • Your client is leaking clientSocket whether connect() succeeds or fails.无论connect()成功还是失败,您的客户端都在泄漏clientSocket

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM