I noticed the incorrect work of the Boost library sockets. Means of this library can bind n sockets to one address. But! If, for example, there are 3 applications - one listens to the socket, the second sends data to it from another socket, and the third sends data to the socket of the first application from the same socket (to itself in essence). Then consider the following combinations:
- We launch 2 copies of the first application and then one copy of the second.
- We start a copy of the first application and the third application.
In situation 1 only the application started first will receive data.
In situation 2 everything depends on the launch order: if the listening application is started first, the data is received and sent normally, and if you start the sending first and then the receiving one, the data is only sent.
Now I will describe examples of these applications.
HOST APPENDIX:
char mess[2000]; boost::asio::ip::udp::endpoint ep = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string("10.177.17.25"), 9007); boost::asio::io_service io; SOCK s("10.177.17.25", 9007, io); void Receive(boost::system::error_code ec_, size_t size_); int _tmain(int argc, _TCHAR* argv[]) { ssasync_receive_from(boost::asio::buffer(mess, 2000), ep, boost::bind(Receive, _1, _2)); this_thread::sleep_for(chrono::seconds(1)); io.run(); system("pause"); return 0; } void Receive(boost::system::error_code ec_, size_t size_) { cout << "\nReceived:\n" << mess << "\n"; ssasync_receive_from(boost::asio::buffer(mess, 2000), ep, boost::bind(Receive, _1, _2)); this_thread::sleep_for(chrono::milliseconds(10)); } SENDING APPENDIX:
int _tmain(int argc, _TCHAR* argv[]) { boost::asio::ip::udp::endpoint ep = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string("10.177.17.25"),9007); boost::asio::io_service io; SOCK s("10.177.17.25", 9007, io); string mess = "ASDFGHSKDJHIUADYUAFD"; while (true) { sssend_to(boost::asio::buffer(mess.c_str(), mess.length()), ep); cout << "\n\nMESSAGE SENT!\n"; io.run(); this_thread::sleep_for(chrono::seconds(1)); } io.run(); system("pause"); return 0; } The SOCK type used in the examples is a wrapper for boost::asio::ip::udp::socket that has only a constructor, below, and the property itself is boost::asio::ip::udp::socket s; . I open the socket as follows:
SOCK::SOCK(string ip_, int port_, boost::asio::io_service& io_) :s(io_) { //boost::asio::ip::udp::socket s; - в свойствах класса using boost::asio::ip::udp; s.open(udp::v4()); s.set_option(udp::socket::reuse_address(true)); s.bind(boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string(ip_), port_)); } Now the question is: why does this work so strangely and how to make it work normally: in situations 1 and 2 all data was received / sent regardless of the launch order.
PS Now I continue to try various options for socket options and launch applications. I found this for situation 2. .:
If you open the sending application, then several recipients, then close the sender and open it again, then one of the recipients will begin to receive. If you close it, it will start accepting the following in the order of opening, and so on.
reuse_addressno reason is evil. - Pavel Mayorov