Прием данных сервера

193
27 декабря 2018, 08:40

Имеется код:

Сервер:

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#pragma comment(lib, "ws2_32.lib")
#include <WinSock2.h>
#include <iostream>
#include <string>
#include <conio.h>
#pragma warnings(disable:4996)
using namespace std;
struct day {
    string name;
    int temp;
};
void generateArray(day *arr, const int SIZE);
int main() {
    WSAData wsaData;
    //Запрашиваемая версия библиотеки winsock. Потом понадобится, чтобы загрузить библиотеку
    WORD dllVersion = MAKEWORD(2, 1);
    //Загружаем библиотеку. Первый параметр - запрашиваемая версия библиотеки. Второй - ссылка на структуру
    if (WSAStartup(dllVersion, &wsaData) != 0) {
        cout << "Error in library loading" << endl;
        exit(1);
    }
    SOCKADDR_IN addr;
    //Localhost
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    //Порт
    addr.sin_port = htons(1111);
    //Семейство портов
    addr.sin_family = AF_INET;
    //Семейство протоколов, протокол
    SOCKET sListen = socket(AF_INET, SOCK_STREAM, NULL);
    bind(sListen, (SOCKADDR*)&addr, sizeof (addr));
    listen(sListen, SOMAXCONN);
    SOCKET newConnection;
    int size = sizeof(SOCKADDR);
    newConnection = accept(sListen, (SOCKADDR*)&addr, &size);
    if (newConnection == 0) {
        cout << "Error in creating newConnection" << endl;
        exit(1);
    }
    else {
        cout << "Client connected" << endl;
        char mes[256];
        const int DAYAM = 7;
        day *arr = new day[DAYAM];

        generateArray(arr, DAYAM);
        recv(newConnection, mes, sizeof(mes), NULL);
        string inDay = mes;
        for (int i = 0; i < DAYAM; i++) {
            if (inDay == arr[i].name) {
                const char* temper = arr[i].temp+"\0";
                send(newConnection, temper, sizeof(temper), NULL);
                break;
            }
        }

    }
    return 0;
}
void generateArray(day * arr, const int SIZE)
{
    arr[0].name = "Monday";
    arr[1].name = "Tuesday";
    arr[2].name = "Wednesday";
    arr[3].name = "Thursday";
    arr[4].name = "Friday";
    arr[5].name = "Saturday";
    arr[6].name = "Sunday";
    for (int i = 0; i < SIZE; i++) {
        arr[i].temp = i + 15;
    }
}

Клиент

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#pragma comment(lib, "ws2_32.lib")
#include <WinSock2.h>
#include <iostream>
#include <string>
#pragma warnings(disable:4996)

using namespace std;
int main() {
    WSAData wsaData;
    //Запрашиваемая версия библиотеки winsock. Потом понадобится, чтобы загрузить библиотеку
    WORD dllVersion = MAKEWORD(2, 1);
    //Загружаем библиотеку. Первый параметр - запрашиваемая версия библиотеки. Второй - ссылка на структуру
    if (WSAStartup(dllVersion, &wsaData) != 0) {
        cout << "Error in library loading" << endl;
        exit(1);
    }
    SOCKADDR_IN addr;
    //Localhost
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    //Порт
    addr.sin_port = htons(1111);
    //Семейство портов
    addr.sin_family = AF_INET;
    //Семейство протоколов, протокол
    SOCKET sListen = socket(AF_INET, SOCK_STREAM, NULL);
    bind(sListen, (SOCKADDR*)&addr, sizeof(addr));
    listen(sListen, SOMAXCONN);
    SOCKET connection = socket(AF_INET,SOCK_STREAM,NULL);
    if (connect(connection, (SOCKADDR*)&addr, sizeof(addr)) != 0) {
        cout << "Error in connection" << endl;
        return 1;
    }
    cout << "Connection succseed!" << endl;

    cout << "Enter the day" << endl;
    string day;
    cin >> day;
    const char *str = day.c_str();
    send(connection, str, sizeof(day), NULL);
    char temper[10];
    recv(connection, temper, sizeof(temper), NULL);
    cout << temper << endl;

    system("pause");
    return 0;
}

Задача - клиент вводит день недели, сервер ему в ответ выдает погоду в этот день. Передача данных от клиента к серверу происходит успешно, а вот обратно - нет. В чем проблема и как исправить? (За то, что очень криво передаю числа, заранее извиняюсь, но так и не разобрался как отправить не const char*)

Answer 1

Прежде всего проблема в практически полном отсутствии проверки ошибок. Например размер полученных данных в recv(newConnection, mes, sizeof(mes), NULL); остается неизвестным, более того, mes может вообще остаться неинициализированным, а функция может не дождаться запрошенных 256 байт. В const char* temper = arr[i].temp+"\0"; происходит смещение указателя явно за пределы массива. sizeof(temper) - это вовсе не длинна строки, а размер указателя, sizeof(day) - это вовсе не длина строки, а размер объекта ::std::string. Также не следует использовать #define _WINSOCK_DEPRECATED_NO_WARNINGS и #pragma warnings(disable:4996).

READ ALSO
Не могу скомпилировать с++ в Сlion в обычном консольном окне

Не могу скомпилировать с++ в Сlion в обычном консольном окне

у меня установлен компилятор MinGW, ошибок программа не выдаетCLion стандартно запускает приложение во встроенной консоли

200
Что делать с ошибкой &ldquo;Error creating SSL context ()&rdquo;?

Что делать с ошибкой “Error creating SSL context ()”?

Делаю обычный Get-запросВот код :

223
Указать рабочую папку для IDE в CMake

Указать рабочую папку для IDE в CMake

Сделал проект с использованием CMake, сгенерировал проект для Visual studio, но когда я в студии создаю новый фаил то он создается в той же папке что...

239
Проблема с обработкой вектора C++ STL

Проблема с обработкой вектора C++ STL

Собственно суть проблемы:

183