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

Nie działające odbieranie wiadomości w boost::asio
GA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 32
0

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

Kopiuj
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));
}
Kopiuj
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);
}
Kopiuj
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";
}
Kopiuj
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.

satirev
  • Rejestracja: dni
  • Ostatnio: dni
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?

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.