Jump to content
  • Advertisement
Sign in to follow this  
_Kami_

asio: Cannot assign requested address

This topic is 2562 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

I have a program that simulates clients and datatraffic (connect to echo server, send 1k chunks 10 times, verify that it got back what it sent, reconnect)
The program will only have 100 concurrent connections.
after about 10k connections has been established (100 active, rest have been closed) I get "Cannot assign requested address". (takes maybe 5-10 seconds)

Its obvious im exhausting some sort of resource
> cat /proc/sys/net/ipv4/ip_local_port_range
55000 65535

Even when starting up the program shortly after its been terminated i still get the same problem.

Now, If I make the clients less aggressive, add some sleep, reconnect only 50% of the time, the problem does not happen, and I can go way past 10k connections.

Is this an issue with the echo server and sockets not closing properly?
Or some other system resource i am hitting that just dont want me to spam connections?

Share this post


Link to post
Share on other sites
Advertisement

Its obvious im exhausting some sort of resource
> cat /proc/sys/net/ipv4/ip_local_port_range
55000 65535


Yes, this is the resource you're exhausting.
The TCP protocol identifies a connection by the four-tuple (source IP, source port, destination IP, destination port)
To avoid late IP packets from an old connection confusing a newly established connection to the same destination host/port, source ports are held in "limbo" for up to 2 minutes before they can get re-used. This is known as the TIME_WAIT state.

Linux is somewhat dumb in this regard -- by default it will "hold back" a port to *any* destination if it's been used for *any* destination -- it really only needs to do this for a particular destination.
Similarly, it only really needs to do it per interface / IP address, so creating more local interfaces with IP addresses, and cycling through which interface you send on, should allow you to greatly exceed the limit of number of possible connections to any particular destination IP/port range.

There are a few things you can do:

1) Substantially increase the ip_local_port_range -- say, from 2000 to 65535
2) Turn on SO_REUSEADDR on sockets before connecting or binding them
3) Perhaps also manually binding sockets to local ports before connecting them to a remote destination, in a cyclic fashion
4) Also, manually bind the outgoing socket to particular interfaces, using multiple local "virtual" interfaces to have many local IP source addresses to choose from

Share this post


Link to post
Share on other sites
thanks for the tips

I do set

m_Socket.set_option(boost::asio::ip::tcp::no_delay(true));
m_Socket.set_option(boost::asio::socket_base::reuse_address(true));

But only after the socket has been connected. Is this the incorrect way to do it? Should I do it before the socket is connected?

Share this post


Link to post
Share on other sites

thanks for the tips

I do set

m_Socket.set_option(boost::asio::ip::tcp::no_delay(true));
m_Socket.set_option(boost::asio::socket_base::reuse_address(true));

But only after the socket has been connected. Is this the incorrect way to do it? Should I do it before the socket is connected?


You need to set re-use address before binding it, or it won't have any effect. Connect will implicitly bind the socket if you haven't already bound it yourself.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!