Я боролся с этим кодом весь день, и я близок к тому, чтобы выдернуть то, что осталось от моих волос.
У меня есть класс сервера и клиента, и первоначальная цель состояла в том, чтобы класс сервера имел список «клиентов», с которыми он мог бы взаимодействовать. Помимо всего множества проблем, у меня есть некоторые основы работы. Сервер регистрирует новые подключения, и я даже могу отправлять строки с клиента.
Вот в чем дело, когда я пытаюсь отправить строку с пробелами, все ломается.
Вот моя функция отправки
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
std::cin >> string
останавливается на первом пробеле! Попробуйтеstd::getline(std::cin, string)
прочитать до первой новой строки. - person Adrian Mole   schedule 29.12.2019Send()
не гарантирует отправку всей строки за один раз. Возвращаемое значение говорит вам, сколько байтов было фактически принято для отправки. Вам нужно вызватьsend()
в цикле, пока все байты не будут фактически отправлены. Точно так же вRun()
вам нужно вызыватьrecv()
в цикле, пока не будут получены все ожидаемые байты. Вы отправляете нулевой терминатор строки, поэтому читайте, пока не придет терминатор. - person Remy Lebeau   schedule 29.12.2019