NanoHttpd / nanohttpd

Tiny, easily embeddable HTTP server in Java.
http://nanohttpd.org
BSD 3-Clause "New" or "Revised" License
6.92k stars 1.69k forks source link

Using NanoHTTPd in Bound Service and locked socket issue #502

Open aloz77 opened 6 years ago

aloz77 commented 6 years ago

I'm using the NanoHTTPd server in a context where a lot of communication to the (single task) activity is required. So I decided to put it in the bound service where start() is called from onBind() and stop() is called from unBind().

Under some very rare conditions (non-reproducible) NanoHTTPd can't start due to BindException: bind failed: EADDRINUSE (Address already in use)

Somehow it looks like the service instance is keeping the port locked. However HTTP requests are always timing out in this situation. So it seems not to be a running nano instance either. As the issue is not reproducible I can't debug into what happens. I have to reboot the device in order to release the port in this situation.

Is there something I should be aware of in this usage scenario?

Or is there any way to make the nano server use another port for incoming connections if the socket is locked?

Euclidite commented 6 years ago

I have actually seen this happening at times as well. I'm running NanoHTTPd on Android, and essentially calling stop() does not release the port right away. I find I have to wait a few seconds for it to completely free up, otherwise the next Start() will fail.

LordFokas commented 6 years ago

@Bartastic I've had something more or less like that happen on the desktop. I think it was windows. Just a strange issue where the socket doesn't release any bound addresses or ports until the process dies and all the resources are finally collected by the OS even though we've clearly told the software to release said resources.

I have no clue how to handle any of that though, much less in Android.

Euclidite commented 6 years ago

@LordFokas For me my service is tied to an on / off toggle. The nanoHttpd Server object is stored / run on a separate thread (lets say ServiceHandler) from the UI. When the user toggles 'off', I disable the toggle, call close() on the server, and then kill the ServiceHandler thread. When the OS reports the ServiceHandler thread has been cleaned up, its safe for me to re-enable the toggle (so that the user can try to turn back on the ServiceHandler thread which automatically starts the nanoHttpd Server).

I've found that with the above workflow I haven't hit the socket issue (except for rare times when I decide to hit debug one too many times and break things!)

LordFokas commented 6 years ago

Well if you're willing to bodge I can see a few ways one could work around that.

While the service is "off", instead either:

vivekpanchal commented 5 years ago

Hey, I am getting the exact same issue is there any way around this problem as I need to work on the same port?

LordFokas commented 5 years ago

@vivekpanchal unless you found a solution yourself, you have to stick to what's going on the discussion above.