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:

  1. We launch 2 copies of the first application and then one copy of the second.
  2. 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.

  • Conclusion - do not use the same socket in different applications. And yes in general, reuse_address no reason is evil. - Pavel Mayorov

1 answer 1

This is not a feature of sockets in the boost. This is a feature of sockets in general. Linux (hereinafter I will write about it, I need to clarify separately about Windows) allows several applications to listen to the same socket. In this case, incoming connections will be thrown round-robin (that is, in turn). Thanks to this they make many interesting things. For example, a web server can run several copies of itself, and although each instance works only in one thread, in fact it turns out to be “multithreading” and with a load balancer from the kernel. But this all applies to the listening socket tcp.

Looking at the code, you can see that there are udp sockets. With them it is usually the case - whoever first socket zabindil, he gets the data on it. Actually, this explains the observed behavior. Why so hard? But the fact is that in udp there is no concept of a server socket (listening) or client. There's just a socket that can send and receive data. Therefore, apparently the system does so.

But if the socket indicates that it is a broadcast / multicast, then everything can work, but again it is very interesting. In the first case described, two listening sockets will receive data from the client. In the second case, also, but only the “echo” will most likely be still - we will receive our own package.

  • Depends. The second option is not to fix the way you want. The first is possible (but again, I'm not sure). - KoVadim
  • If you want to use a multicast group, then you need to take the ip right. Just like that on any apyi impossible. - KoVadim
  • If in brief, it is necessary that in different programs data come to this socket and can be sent from it. For one address there is only 1 receiving and 1 sending - Dmitry
  • Perhaps you need a proxy application. - KoVadim
  • Yes, it will be so, if I do not decide how to solve this problem - Dmitry