Nie działające odbieranie wiadomości w boost::asio

0

Siema.
Mam problem z odbieraniem wiadomości w aplikacji typu klient/serwer.

void Connection::sendMessage(Message msg)
{
	Messages::UniversalMessage universalMessage;
	universalMessage.set_type(msg.type);
	universalMessage.set_payloadsize(sizeof(msg.message));
	std::string uniMsg = universalMessage.SerializeAsString();
	socket.write_some(buffer(uniMsg));
	socket.write_some(buffer(msg.message));
}
Message Connection::receiveMessage()
{
	//std::string uniMsg;
	char *uniMsg = new char[sizeof(Messages::UniversalMessage)];
	size_t bytes = read(socket, buffer(uniMsg, sizeof(Messages::UniversalMessage)));
	std::cout << bytes << " " << sizeof(Messages::UniversalMessage);
	Messages::UniversalMessage uni;
	uni.ParseFromString(uniMsg);
	//std::string msg;
	char *msg = new char[uni.payloadsize()];
	read(socket, buffer(msg, uni.payloadsize()));
	std::string message(msg);
	delete []uniMsg;
	delete[]msg;
	return Message(uni.type(), message);
}
void Server::run()
{
	ip::tcp::acceptor acceptor(connection->service, ip::tcp::endpoint(ip::tcp::v4(), 1302));
	std::cout << "SERVER STARTED\n";
	while (networkEngine->isRunning)
	{
		acceptor.accept(connection->socket);
		Message msg = connection->receiveMessage();
		if (msg.type == MessageType::UniversalMessage_MessageType_CLIENT_HELLO)
		{
			Messages::ServerResponse gtfo;
			gtfo.set_ok(false);
			connection->sendMessage(Message(MessageType::UniversalMessage_MessageType_SERVER_RESPONSE, gtfo.SerializeAsString()));
		}
		connection->socket.close();
	}
	std::cout << "SERVER STOPED\n";
}
void Client::run()
{
	connection->connect();
	std::cout << "CLIENT STARTED\n";
	while (networkEngine->isRunning)
	{
		Messages::ClientHello hello;
		connection->sendMessage(Message(MessageType::UniversalMessage_MessageType_CLIENT_HELLO, hello.SerializeAsString()));
		Message received = connection->receiveMessage();
		if (received.type == MessageType::UniversalMessage_MessageType_SERVER_RESPONSE)
		{
			Messages::ServerResponse response;
			response.ParseFromString(received.message);
			if (!response.ok())
			{
				networkEngine->isRunning = false;
				std::cout << "SEVER REJECTED CONNECTION" << std::endl;
			}
		}
	}
	std::cout << "CLIENT STOPED\n";
	connection->disconnect();
}

Zarówno klient jak i serwer działają w osobnych wątkach.

0

Do wysłania danych używasz write_some, który może zwrócić sterowanie do następnej instrukcji zaraz po tym jak wyśle tylko część danych z buffora. Odczytujesz natomiast używając blokującego read i czekasz na tyle danych ile pomieści buffor. Wysyłaj dane (w pętli) do czasu aż wyślesz wszystko co chcesz, odczytuj na podobnej zasadzie.
Poza tym pokaż jak odpalasz serwer, tj. czy Twój io_service na pewno ma zawsze jakieś zadanie do wykonania, czy czasem nie zamyka się zaraz po starcie.
Kilka uwag:

  • rozdziel akceptowanie połączenia od obsługi klienta
  • networkEngine->isRunning to jest sharewane między serwerem, a klientem? Zapewniasz atomość dostępu do tej zmiennej?

1 użytkowników online, w tym zalogowanych: 0, gości: 1