Winsock2: когда я пытаюсь отправить строку с пробелами, функция прекращает отправку, когда встречает пробел

Я боролся с этим кодом весь день, и я близок к тому, чтобы выдернуть то, что осталось от моих волос.

У меня есть класс сервера и клиента, и первоначальная цель состояла в том, чтобы класс сервера имел список «клиентов», с которыми он мог бы взаимодействовать. Помимо всего множества проблем, у меня есть некоторые основы работы. Сервер регистрирует новые подключения, и я даже могу отправлять строки с клиента.

Вот в чем дело, когда я пытаюсь отправить строку с пробелами, все ломается.

Вот моя функция отправки

    int Send(std::string message)
    {
        const char* cstr = message.c_str();
        size_t      len = message.length();

        //The +1 is for the \0 character that c_str() adds
        //this->server is a socket that has already been connected to and accepted by the server
        int bytes = send(this->server, cstr, len + 1, 0);  
        return bytes;
    }

На стороне сервера:

void Run()
    {
        char buffer[1024];
        while (1)
        {
            listen(server, 0);
            SOCKET incoming_sock;
            int clientAddrSize = sizeof(clientAddr);
            if ((incoming_sock = accept(server, (SOCKADDR*)&clientAddr, &clientAddrSize)) != INVALID_SOCKET)
            {
                std::cout << "Error: " << WSAGetLastError() << std::endl;
                std::cout << "Connection occured " << printIP(clientAddr.sin_addr.s_addr) << std::endl;
                int bytes = recv(incoming_sock, buffer, sizeof(buffer), 0);
                std::cout << bytes << " Bytes With the message: " << buffer << std::endl;
                std::cout << "Error: " << WSAGetLastError() << std::endl;
            }
            else
            {
                std::cout << "Error: " << WSAGetLastError() << std::endl;
            }
        }
    }

Вот странная часть:

В основной функции моего клиента, когда я предопределяю строку, например «Hello World», сервер отлично ее распечатывает. Но когда я пытаюсь проанализировать пользовательский ввод с помощью std::cin, сообщение прерывается после первого пробела.

Основная функция клиента:

#include "Client.h"
#include <iostream>

int main()
{
    Client c("127.0.0.1", 5555, 1);
    std::string msg = "Hello World!";
    while (msg.compare("exit") != 0)
    {

        //std::cout << "Send: ";
        //std::cin >> msg;
        int bytes = c.Send(msg);
        std::cout << "Sent \"" << msg << "\"" << "Bytes: " << bytes << std::endl;
    }
    while (1);
    return 0;
}

И вывод на сервер:

In the Constructor Error code: 0Bind code: 0
Error: 0
Connection occured 127.0.0.0
13 Bytes With the message: Hello World!
Error: 0

Если я раскомментирую ввод и наберу «Hello» в приглашении, я получу следующий вывод:

In the Constructor Error code: 0Bind code: 0
Error: 0
Connection occured 127.0.0.0
6 Bytes With the message: hello
Error: 0

Но если я наберу "Hello World!" Я получаю только:

In the Constructor Error code: 0Bind code: 0
Error: 0
Connection occured 127.0.0.0
6 Bytes With the message: Hello
Error: 0

person bari eune    schedule 29.12.2019    source источник
comment
std::cin >> string останавливается на первом пробеле! Попробуйте std::getline(std::cin, string) прочитать до первой новой строки.   -  person Adrian Mole    schedule 29.12.2019
comment
Кстати, ваш код Send() не гарантирует отправку всей строки за один раз. Возвращаемое значение говорит вам, сколько байтов было фактически принято для отправки. Вам нужно вызвать send() в цикле, пока все байты не будут фактически отправлены. Точно так же в Run() вам нужно вызывать recv() в цикле, пока не будут получены все ожидаемые байты. Вы отправляете нулевой терминатор строки, поэтому читайте, пока не придет терминатор.   -  person Remy Lebeau    schedule 29.12.2019


Ответы (1)


std::cin >> msg; читается до первого пробела. Если вы хотите прочитать всю строку до символа конца строки, сделайте это

std::getline(cin, msg);
person Igor Tandetnik    schedule 29.12.2019
comment
оно работает. Оглядываясь назад, я должен был попытаться распечатать то, что было на входе. Сэкономил бы мне несколько часов. Благодарю вас! - person bari eune; 29.12.2019