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

时间:2019-09-19 05:37:27

标签: c++ tcp winsock

我尝试使客户端发送消息的应用程序和服务器使用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

2 个答案:

答案 0 :(得分:-1)

如果出现错误,则应使用GetLastError()函数获取错误代码,每个syscall都可以报告不同的错误集,您可以在MS网站上检查错误代码的定义。

答案 1 :(得分:-1)

编辑:发现了新问题-我仍然不相信使用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)。

这部分很好。

但是,当客户端必须连接到服务器时,您不能只说:“连接到任何东西!”并期望它找到您的服务器(或任何其他东西)。因此,当您尝试连接客户端套接字时,必须为其提供服务器的实际地址。

我找到了一个执行此操作的示例:

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)

如果localhost127.0.0.1)对您不起作用,请将地址更改为适合您服务器的地址。