为什么我的客户端无法连接到服务器?

Why can't my client connect to the server?

我尝试使用 winsock TCP c++ 在同一台机器上创建客户端发送消息和服务器响应的应用程序。问题是在服务器等待客户端连接后,我 运行 客户端代码在连接和退出时停止。这是我的代码。

服务器:

#include <stdio.h>
#include <tchar.h>
#include <winsock2.h>
#include <iostream>

#define MY_PORT 8888

using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
    //Init Winsock
    WSADATA SData;

    if (WSAStartup(0x0202, &SData) != 0)
    {
        cout << "KHONG THE KHOI DONG WINSOCK";
        return 1;
    }

    //Init Socket
    int listeningSocket;
    if ((listeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    {
        perror("socket failed");
        WSACleanup();
        exit(EXIT_FAILURE);
    }

    //Set IP and PORT
    sockaddr_in server_addr;

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(MY_PORT);
    server_addr.sin_addr.s_addr = INADDR_ANY;

    //Bind
    if (bind(listeningSocket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
    {
        perror("bind failed");
        closesocket(listeningSocket);
        WSACleanup();
        exit(EXIT_FAILURE);
    }

    //Listen
    if (listen(listeningSocket, 5) < 0)
    {
        perror("listen failed");
        closesocket(listeningSocket);
        WSACleanup();
        exit(EXIT_FAILURE);
    }

    //Accept
    int new_socket;
    sockaddr_in client_addr;

    int nSizeAddr = sizeof(sockaddr);
    if (new_socket = accept(listeningSocket, (struct sockaddr *)&client_addr, &nSizeAddr) < 0)
    {
        perror("accept failed");
        closesocket(listeningSocket);
        WSACleanup();
        exit(EXIT_FAILURE);
    }

    while (1)
    {
        //recv
        char buff[100];
        if (recv(new_socket, buff, 100, 0) < 0)
        {
            perror("recv failed");
            closesocket(listeningSocket);
            WSACleanup();
            exit(EXIT_FAILURE);
        }
        cout << buff << endl;

        //send
        string sndStr = "Da nhan";
        if (send(new_socket, sndStr.c_str(), sndStr.size(), 0) < 0)
        {
            perror("send failed");
            closesocket(listeningSocket);
            WSACleanup();
            exit(EXIT_FAILURE);
        }

    }
    //close socket
    closesocket(new_socket);

    //Cleanup winsock
    WSACleanup();

    return 0;
}

客户:

#include <stdio.h>
#include <tchar.h>
#include <winsock2.h>
#include <iostream>
#include <string>

#define MY_PORT 8888

using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
    //Init winsock
    WSADATA SData;

    if (WSAStartup(0x0202, &SData) != 0) 
    {
        cout << "KHONG THE KHOI DONG WINSOCK";
        return 1;
    }
    //Init socket
    int clientSocket;
    if (clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) < 0)
    {
        perror("socket failed");
        WSACleanup();
        exit(EXIT_FAILURE);
    }

    //Set IP and PORT
    sockaddr_in server_addr;

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(MY_PORT);
    server_addr.sin_addr.s_addr = INADDR_ANY; //Vi Client-Server chung 1 may

    //Connect
    if (connect(clientSocket, (SOCKADDR*)&server_addr, sizeof(server_addr)) < 0)
    {
        perror("connect failed");
        closesocket(clientSocket);
        WSACleanup();
        exit(EXIT_FAILURE);
    }

    while (1)
    {
        //Send 
        string sndStr;
        getline(cin, sndStr);
        if (send(clientSocket, sndStr.c_str(), sndStr.size(), 0) < 0)
        {
            perror("send failed");
            closesocket(clientSocket);
            WSACleanup();
            exit(EXIT_FAILURE);
        }
        //Recv
        char buff[100];
        if (recv(clientSocket, buff, 100, 0) < 0)
        {
            perror("recv failed");
            closesocket(clientSocket);
            WSACleanup();
            exit(EXIT_FAILURE);
        }
        cout << buff << endl;
    }
    //Close socket
    closesocket(clientSocket);

    //Cleanup Winsock
    WSACleanup();
}

接受步骤出错,但我不知道错误名称是什么。我该如何解决?

client_socket 值变成 INVALID_SOCKET

编辑:发现新问题 - 我仍然不相信使用 INADDR_ANY 作为客户端地址是好的,但这实际上不是这里的问题。

相反,问题出在行中:

if (clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) < 0)

注意<的优先级高于=,所以这里给clientSocket赋了一个布尔值。服务器代码中的类似行添加了括号,使其正常工作。

服务器代码中的工作行:

if ((listeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)

旧答案:我仍然坚持这一点,但这不是这里的问题

.

这就是你的问题(在客户端):

server_addr.sin_addr.s_addr = INADDR_ANY; //Vi Client-Server chung 1 may

套接字的工作方式是创建一个服务器套接字来侦听传入的连接,并在创建时告诉它接受来自谁的连接。来自特定地址、地址范围或任何人。第三个选项是这里最常见的选项,也是您在服务器中选择的选项(绑定到地址INADDR_ANY)。

这部分不错

但是,当客户端必须连接到服务器时,您不能只说:"Connect to whatever!" 并期望它找到您的服务器(或任何东西)。所以当你尝试连接客户端套接字时,你必须给它服务器的实际地址。

我找到了如何执行此操作的示例:

serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);

// Convert IPv4 and IPv6 addresses from text to binary form 
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0)
{
    printf("\nInvalid address/ Address not supported \n");
    return -1;
}

if (connect(sock, (struct sockaddr*) & serv_addr, sizeof(serv_addr)) < 0)

如果 localhost (127.0.0.1) 不适合您,请将地址更改为正确的服务器地址。