EsotericSoftware / kryonet

TCP/UDP client/server library for Java, based on Kryo
BSD 3-Clause "New" or "Revised" License
1.82k stars 419 forks source link

Utilize SO_REUSEADDR #83

Closed sreich closed 9 years ago

sreich commented 9 years ago

it's my impression that the socket code doesn't utilize SO_REUSEADDR, which means it can cause problems with the socket being in limbo and failing to connect on localhost on many platforms, after it has been started/restarted.

see http://www.unixguide.net/network/socketfaq/4.5.shtml

NathanSweet commented 9 years ago

You would need to exhaust your ports. This is definitely over 16k and can be as high as 64k. I doubt anyone is using half that many ports with KryoNet. Is this a theoretical problem or something you are experiencing?

On Thu, Feb 5, 2015 at 7:04 PM, Shaun Reich notifications@github.com wrote:

it's my impression that the socket code doesn't utilize SO_REUSEADDR, which means it can cause problems with the socket being in limbo and failing to connect on localhost on many platforms, after it has been started/restarted.

see http://www.unixguide.net/network/socketfaq/4.5.shtml

— Reply to this email directly or view it on GitHub https://github.com/EsotericSoftware/kryonet/issues/83.

sreich commented 9 years ago

no, i'm only using one port (tcp), this isn't about port exhaustion, it's about port reuse. specifically since the server is at one fixed port, throughout all new instances. so my understanding is that a shutdown of the server at say, port 5000, and a restart of the server at that port, the port could still be locked and thus fail. the linked socket faq poorly explains a little bit of it.

but anyways, yes i experience occasional "port/address in use" bind issues just running both on local host. it seems to be more likely to happen if i start immediately after stopping. it was suggested to me by someone more familiar with networking, that this is a common mistake on server side code, and looking at the code, apparently nio does not have this set by default, and kryonet does not set this either.

NathanSweet commented 9 years ago

I can restart a KryoNet server without an issue with TIME_WAIT. Typically sockets stay in TIME_WAIT for 1 minute, so I think if there was a problem with restarting the server it would be easily apparent.

I'm not against using SO_REUSEADDR, but I'm not sure there is a problem that needs fixing.

On Fri, Feb 6, 2015 at 12:02 AM, Shaun Reich notifications@github.com wrote:

no, i'm only using one port (tcp), this isn't about port exhaustion, it's about port reuse. specifically since the server is at one fixed port, throughout all new instances. so my understanding is that a shutdown of the server at say, port 5000, and a restart of the server at that port, the port could still be locked and thus fail. the linked socket faq poorly explains a little bit of it.

but anyways, yes i experience occasional "port/address in use" bind issues just running both on local host. it seems to be more likely to happen if i start immediately after stopping. it was suggested to me by someone more familiar with networking, that this is a common mistake on server side code, and looking at the code, apparently nio does not have this set by default, and kryonet does not set this either.

— Reply to this email directly or view it on GitHub https://github.com/EsotericSoftware/kryonet/issues/83#issuecomment-73148961 .

sreich commented 9 years ago

hm, indeed. so can i, tested 50+ times starting, restarting..killing, stress testing it...

documentation everywhere seems to suggest that SO_REUSEADDR is what one should use, and that you'd encounter the problem without it, but that doesn't seem to happen in reality. Must be some weird thing intellij is doing when in debugging mode, possibly not killing the proc fully even though it says it does, which is interesting because it's happened probably 20 times over the past month.

sorry for the noise. if i encounter it again, i'll have to do a netstat, see if it's actually in TIME_WAIT, or just a rogue process...