Как построить эхо-сервер и клиент, используя локальную датаграмму asio?
// сервер
#include <boost/asio.hpp>
int main()
{
::unlink("local_socket");
boost::asio::io_service io_service;
boost::asio::local::datagram_protocol::endpoint endpoint("local_socket");
boost::asio::local::datagram_protocol::socket socket(io_service, endpoint);
char recv_buf[1024];
while (1)
{
boost::asio::local::datagram_protocol::endpoint senderEndpoint;
size_t len = socket.receive_from(
boost::asio::buffer(recv_buf, 1024), senderEndpoint);
printf("***%s###\n", senderEndpoint.path().c_str());
socket.send_to(
boost::asio::buffer(recv_buf, len), senderEndpoint);
}
return 0;
}
// клиент
#include <boost/asio.hpp>
enum { max_length = 1024 };
int main(int argc, char* argv[])
{
boost::asio::io_service io_service;
boost::asio::local::datagram_protocol::endpoint endpoint("local_socket");
boost::asio::local::datagram_protocol::socket socket(io_service);
socket.open();
std::cout << "Enter message: ";
char request[max_length];
std::cin.getline(request, max_length);
size_t request_length = strlen(request);
socket.send_to(
boost::asio::buffer(request, request_length), endpoint);
char reply[max_length];
size_t reply_length = socket.receive_from(
boost::asio::buffer(reply, max_length), endpoint);
std::cout << "Reply is: ";
std::cout.write(reply, reply_length);
std::cout << "\n";
return 0;
}
Когда я использую клиента для отправки "123", а сервер является coredump с:
*** ### прекращение вызова после выброса экземпляра 'boost:: exception_detail:: clone_impl
'what (): send_to: неверный аргумент прерван
2 ответа
Причина, по которой сервер прерывает работу, заключается в том, что senderEndpoint
не заполняется призывом к receive_from
- клиентский сокет не привязан ни к чему, поэтому он не отправляет файловый дескриптор, на который следует получать ответы. Если мы осуществим рефакторинг клиента следующим образом:
#include <iostream>
#include <boost/asio.hpp>
enum { max_length = 1024 };
int main(int argc, char* argv[])
{
boost::asio::io_service io_service;
boost::asio::local::datagram_protocol::endpoint server_endpoint("local_socket");
// Create client endpoint on which to receive response
std::string client_addr = "local_socket.";
client_addr += std::to_string(::getpid());
::unlink(client_addr.c_str());
boost::asio::local::datagram_protocol::endpoint client_endpoint(client_addr.c_str());
boost::asio::local::datagram_protocol::socket socket(io_service, client_endpoint);
std::cout << "Enter message: ";
char request[max_length];
std::cin.getline(request, max_length);
size_t request_length = strlen(request);
socket.send_to(
boost::asio::buffer(request, request_length), server_endpoint);
char reply[max_length];
size_t reply_length = socket.receive_from(
boost::asio::buffer(reply, max_length), client_endpoint);
std::cout << "Reply is: ";
std::cout.write(reply, reply_length);
std::cout << "\n";
return 0;
}
тогда это работает как ожидалось:
Enter message: 123
***local_socket.29635###
Reply is: 123