Я написал базовое клиент-серверное приложение на C++ с использованием библиотеки asio
. Клиент отправляет сообщения с консоли на сервер.Websockets with C++ asio library weird behavior
Если я запускаю его на локальном хосте на Linux или Windows, он отлично работает. Однако, когда я запускаю его на своем реальном сервере, я получаю странное поведение. Каждый раз, когда я отправляю сообщение, сразу после отправки другого сообщения, которое содержит мусор или пусто. Иногда это случается, иногда нет. Но это происходит в большинстве случаев. Я пробовал использовать другой порт.
Например, если я посылаю сообщения 1, 2 и 3 это то, что я вижу в консоли сервера:
Что я могу делать неправильно?
server.cpp - почти тот же код, как видно here
#define ASIO_STANDALONE
#include <iostream>
#include <asio.hpp>
using asio::ip::tcp;
const std::size_t max_length = 2048;
const unsigned short PORT = 15562;
class Session
: public std::enable_shared_from_this<Session>
{
public:
Session(tcp::socket server_socket)
: _session_socket(std::move(server_socket))
{
}
void start()
{
do_read();
}
private:
void do_read()
{
auto self(shared_from_this()); // shared_ptr instance to this
// Start an asynchronous read.
// This function is used to asynchronously read data from the stream socket.
_session_socket.async_read_some(asio::buffer(_data, max_length),
[this, self](std::error_code error, std::size_t length)
{
if (!error)
{
std::cout << "Data RECEIVED: " << std::endl;
std::cout << _data << std::endl;
do_write(length);
}
});
}
void do_write(std::size_t length)
{
auto self(shared_from_this()); // shared_ptr instance to this
// Start an asynchronous write.
// This function is used to asynchronously write data to the stream socket.
strncpy(_data, "Hi, from the server", max_length);
asio::async_write(_session_socket, asio::buffer(_data, length),
[this, self](std::error_code error, std::size_t /*length*/)
{
if (!error)
{
do_read();
}
});
}
tcp::socket _session_socket;
char _data[max_length];
};
class server
{
public:
server(asio::io_service &io_service, const tcp::endpoint &endpoint)
: _server_socket(io_service),
_server_acceptor(io_service, endpoint)
{
}
void do_accept()
{
// Start an asynchronous accept.
// This function is used to asynchronously accept a new connection into a socket.
_server_acceptor.async_accept(_server_socket,
[this](std::error_code error)
{
// Accept succeeded
if (!error)
{
// Create a session
auto session = std::make_shared<Session>(
std::move(_server_socket));
session->start();
}
// Continue to accept more connections
do_accept();
});
}
private:
tcp::acceptor _server_acceptor;
tcp::socket _server_socket;
};
int main()
{
try
{
asio::io_service io_service; // io_service provides functionality for sockets, connectors, etc
tcp::endpoint endpoint(tcp::v4(), PORT); // create an endpoint using a IP='any' and the specified PORT
server server(io_service, endpoint); // create server on PORT
server.do_accept();
std::cout << "Server started on port: " << PORT << std::endl;
io_service.run();
}
catch (std::exception &e)
{
std::cerr << "Exception: " << e.what() << "\n"; // Print error
}
return 0;
}
client.cpp - почти такой же код, как показано here
#define ASIO_STANDALONE
#include <iostream>
#include <asio.hpp>
using asio::ip::tcp;
int main(int argc, char *argv[])
{
asio::io_service io_service;
tcp::socket socket(io_service);
tcp::resolver resolver(io_service);
// Connect
asio::connect(socket, resolver.resolve({"localhost", "15562"}));
for (int i = 0; i < 10; ++i)
{
std::cout << "Enter message to sent to server:" << std::endl;
char client_message[2048];
std::cin.getline(client_message, 2048);
// Send message to server
asio::write(socket, asio::buffer(client_message, 2048));
char server_message[2048];
// Read message from server
asio::read(socket, asio::buffer(server_message, 2048));
std::cout << "Reply is: " << std::endl;
std::cout << server_message << std::endl;
}
return 0;
}
Очень возможно, что сервер не получает всего сообщения за один выстрел, а в результате '_data' не завершает нуль. То же самое для 'server_message' в клиенте. – user4581301
@ user4581301 Каков правильный способ обработки этой ситуации в коде? Как я могу узнать, когда получил все сообщение? Я просто распечатываю '_data'. Если у вас есть знания о веб-сайтах, взгляните на мой [другой вопрос] (http://stackoverflow.com/questions/36557865/websockets-using-asio-c-library-for-the-server-and-javascript-as -клиент) тоже, если вы можете – dimitris93