【问题标题】:Sockets: client cannot connect to other computer/server套接字:客户端无法连接到其他计算机/服务器
【发布时间】:2012-01-10 18:10:54
【问题描述】:

我有一个问题,到目前为止我不知道如何解决它。 我已经通过 Windows 套接字创建了标准服务器和客户端,它在我的 PC 上运行良好(如果我运行服务器然后运行它们连接的客户端)但是当服务器在我的计算机上运行时我不知道如何让它工作朋友(他运行服务器部分)并且客户端在我的 PC 上启动。 他的IP:192.168.1.6 我的IP:192.168.1.2 为什么我无法连接到他机器上运行的服务器应用程序? 它应该有效吗?除了建立连接我还需要做什么吗?

服务器:



    // C++ from Visual Studio 2008 Pro Edition
        //#include "stdafx.h"
        #include 
        #include 
        #include 
        #include 
        //#pragma comment(lib, "ws2_32.lib") //not necessary becouse additional dependency added to linker
    // Microsoft Development Environment 2003 - Version 7.1.3088
    // Copyright (r) 1987-2002 Microsoft Corporation. All Right Reserved
    // Microsoft .NET Framework 1.1 - Version 1.1.4322
    // Copyright (r) 1998-2002 Microsoft Corporation. All Right Reserved
    // Run on Windows XP Pro machine, version 2002, SP 2
    //  already included
    // WINVER = 0x0501 for Xp already defined in windows.h


    int main(){
    WORD wVersionRequested;
    WSADATA wsaData={0};
    int wsaerr;

    // Using MAKEWORD macro, Winsock version request 2.2
    wVersionRequested = MAKEWORD(2, 2);
    wsaerr = WSAStartup(wVersionRequested, &wsaData);
    if (wsaerr != 0){
        /* Tell the user that we could not find a usable WinSock DLL.*/
        printf("Server: The Winsock dll not found!\n");
        return 0;
    }else{
           printf("Server: The Winsock dll found!\n");
           printf("Server: The status: %s.\n", wsaData.szSystemStatus);
    }

    /* Confirm that the WinSock DLL supports 2.2.*/
    /* Note that if the DLL supports versions greater    */
    /* than 2.2 in addition to 2.2, it will still return */
    /* 2.2 in wVersion since that is the version we      */
    /* requested.                                        */
    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2 ){
    /* Tell the user that we could not find a usable WinSock DLL.*/
    printf("Server: The dll do not support the Winsock version %u.%u!\n", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));
           WSACleanup();
           return 0;
    }else{
           printf("Server: The dll supports the Winsock version %u.%u!\n", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));
           printf("Server: The highest version this dll can support: %u.%u\n", LOBYTE(wsaData.wHighVersion), HIBYTE(wsaData.wHighVersion));
    }
    //////////Create a socket////////////////////////
    //Create a SOCKET object called m_socket.
    SOCKET m_socket;
    // Call the socket function and return its value to the m_socket variable.
    // For this application, use the Internet address family, streaming sockets, and the TCP/IP protocol.
    // using AF_INET family, TCP socket type and protocol of the AF_INET - IPv4
    m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    // Check for errors to ensure that the socket is a valid socket.
    if (m_socket == INVALID_SOCKET){
        printf("Server: Error at socket(): %ld\n", WSAGetLastError());
        WSACleanup();
        //return 0;
    }else{
        printf("Server: socket() is OK!\n");
    }

    ////////////////bind//////////////////////////////
    // Create a sockaddr_in object and set its values.
    sockaddr_in service;

    // AF_INET is the Internet address family.
    service.sin_family = AF_INET;
    // "127.0.0.1" is the local IP address to which the socket will be bound.
    service.sin_addr.s_addr = htons(INADDR_ANY); //inet_addr("192.168.1.2");
    // 55555 is the port number to which the socket will be bound.
    // using the htons for big-endian
    service.sin_port = htons(55555);

    // Call the bind function, passing the created socket and the sockaddr_in structure as parameters.
    // Check for general errors.
    if (bind(m_socket, (SOCKADDR*)&service, sizeof(service)) == SOCKET_ERROR){
        printf("Server: bind() failed: %ld.\n", WSAGetLastError());
        closesocket(m_socket);
        //return 0;
    }else{
        printf("Server: bind() is OK!\n");
    }
    // Call the listen function, passing the created socket and the maximum number of allowed
    // connections to accept as parameters. Check for general errors.
    if (listen(m_socket, 1) == SOCKET_ERROR)
           printf("Server: listen(): Error listening on socket %ld.\n", WSAGetLastError());
    else{
        printf("Server: listen() is OK, I'm waiting for connections...\n");
    }

    // Create a temporary SOCKET object called AcceptSocket for accepting connections.
    SOCKET AcceptSocket;

    // Create a continuous loop that checks for connections requests. If a connection
    // request occurs, call the accept function to handle the request.
    printf("Server: Waiting for a client to connect...\n");
    printf("***Hint: Server is ready...run your client program...***\n");
    // Do some verification...
    while (1){
        AcceptSocket = SOCKET_ERROR;

          while (AcceptSocket == SOCKET_ERROR){
            AcceptSocket = accept(m_socket, NULL, NULL);
           }
       // else, accept the connection...
       // When the client connection has been accepted, transfer control from the
       // temporary socket to the original socket and stop checking for new connections.
        printf("Server: Client Connected!\n");
        m_socket = AcceptSocket;
        break;
    }
    system("pause");
    return 0;
    }

客户:



    // C++ from Visual Studio 2008 Pro Edition
        //#include "stdafx.h"
        #include 
        #include 
        #include 
        #include 
        //#pragma comment(lib, "ws2_32.lib") //not necessary becouse additional dependency added to linker
        // Microsoft Development Environment 2003 - Version 7.1.3088
        // Copyright (r) 1987-2002 Microsoft Corporation. All Right Reserved
        // Microsoft .NET Framework 1.1 - Version 1.1.4322
        // Copyright (r) 1998-2002 Microsoft Corporation. All Right Reserved
        // Run on Windows XP Pro machine, version 2002, SP 2
        //  already included
        // WINVER = 0x0501 for Xp already defined in windows.h
        // A sample of client program

        int main(){
            // Initialize Winsock.
            WSADATA wsaData;
            int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
            if (iResult != NO_ERROR)
                 printf("Client: Error at WSAStartup().\n");
            else
                 printf("Client: WSAStartup() is OK.\n");
            // Create a socket.
            SOCKET m_socket;
            m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

            if (m_socket == INVALID_SOCKET){
                printf("Client: socket() - Error at socket(): %ld\n", WSAGetLastError());
                WSACleanup();
                return 7;
            }else
               printf("Client: socket() is OK.\n");

            // Connect to a server.
            sockaddr_in clientService;

            clientService.sin_family = AF_INET;
            //clientService.sin_addr.s_addr = inet_addr("77.64.240.156");
            clientService.sin_addr.s_addr = inet_addr("192.168.1.6");
            clientService.sin_port = htons(55555);

            if (connect(m_socket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR){
                printf("Client: connect() - Failed to connect.\n");
                WSACleanup();
                return 6;
            }

            // Send and receive data
            int bytesSent;
            int bytesRecv = SOCKET_ERROR;
            // Be careful with the array bound, provide some checking mechanism
            char sendbuf[200] = "Client: Sending some test string to server...";
            char recvbuf[200] = "";

            bytesSent = send(m_socket, sendbuf, strlen(sendbuf), 0);
            printf("Client: send() - Bytes Sent: %ld\n", bytesSent);

            while(bytesRecv == SOCKET_ERROR){
                bytesRecv = recv(m_socket, recvbuf, 32, 0);
                if (bytesRecv ...
            return 0;
        }

【问题讨论】:

  • 你朋友的电脑在同一个网络上吗?如果不是,则 IP 无用且无法通过 Internet 运行。你需要他的外网IP,有网站可以查到:whatismyip.com
  • 我不知道你可以在不传递 sockaddr_in 和长度指针参数的情况下调用“accept”。刚查了MSDN,好像没问题。很有趣。

标签: windows winapi sockets


【解决方案1】:

尝试在您朋友的计算机上运行服务器,然后转到您的计算机并从命令提示符运行:

telnet 192.168.1.6 55555

看看它是否完全连接。如果不是,那么问题不在于您的客户端代码。考虑路由或防火墙问题的可能性。

【讨论】:

  • 对不起,我的IP弄错了,现在正确了:他的IP:192.168.1.6 我的IP:192.168.1.2
  • 现在我无法运行我的服务器,我稍后再试一次,但也许 ping 就足够了?
  • ping 输出:Badanie 192.168.1.6 z uľyciem 32 bajt˘w danych: Odpowied« z 192.168.1.6: bajt˘w=32 czas=1ms TTL=128 Odpowied« z 192.168.1.6: bajt˘ w=32 czas=1ms TTL=128 Odpowied« z 192.168.1.6: bajt˘w=32 czas=1ms TTL=128 Odpowied« z 192.168.1.6: bajt˘w=32 czas=1ms TTL=128 Statystyka badania ping dla 192.168 .1.6: Pakiety: Wysane = 4, Odebrane = 4, Utracone = 0 (0% straty), Szacunkowy czas bĄdzenia pakiet˘w w w millisekundach: 最小值 = 1 ms, Maksimum = 1 ms, Czas redni = 1 ms
  • 服务器运行成功:它创建套接字然后监听客户端。但是我的客户端(我的电脑)无法连接到我朋友的 IP 和端口 5555,因为它是服务器套接字的端口。
  • @cf16 - 我的超能力告诉我服务器上的防火墙阻止了端口。通过允许 EXE 的端口或规则在控制面板中修复此问题。 catfood 正在引导您朝着正确的方向前进。启动服务器后,是否可以在同一台 PC 上执行“telnet localhost 55555”?
猜你喜欢
  • 1970-01-01
  • 2013-12-05
  • 2014-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-25
  • 2016-06-08
  • 2023-01-30
相关资源
最近更新 更多