Почему мой клиент не может подключиться к серверу? - PullRequest
0 голосов
/ 19 сентября 2019

Я пытаюсь сделать так, чтобы клиент отправлял сообщение, а сервер отвечал на одном компьютере, используя 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 голосов
/ 19 сентября 2019

РЕДАКТИРОВАТЬ: Обнаружена новая проблема - я все еще не верю, что использование 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)

Изменить адресна правильный для вашего сервера, если localhost (127.0.0.1) не работает для вас.

0 голосов
/ 19 сентября 2019

В случае ошибки, Вы должны использовать функцию GetLastError () для получения кода ошибки. Каждый системный вызов имеет различный набор ошибок, о которых он может сообщить, вы можете проверить определение кода ошибки на сайте MS.

...