Taimoor Mirza <mooni_mi...@hotmail.com> writes: > Hi Everyone, > I am trying to use QEMU's port forwarding option with my application > and have observed following difference in behaviour on Windows and > Linux: > * If I relaunch QEMU with same host and guest port redirection values > on Linux, it throws following error:qemu-system-arm: could not set up > host forwarding rule 'tcp:8080::8080'qemu-system-arm: Device 'user' > could not be initialized > This makes sense as first launch of QEMU creates a socket and binds it > to host port 8080 and starts listening for connection. So any > subsequent request to bind to same port fails that results in host > forwarding rule error. > * But If I relaunch QEMU with same host and guest port redirection > values on Windows, it does not throw any error and second launch also > gets successful. But connection requests are only received by first > launch's socket and second launch does not get any connection > requests. > I looked at QEMU source code and found out that it sets SO_REUSEADDR > socket option before binding to host port. It looks to me that > behavior of SO_REUSEADDR option is different on Windows and Linux. > On Windows, As per MSDN, "“The SO_REUSEADDR socket option allows a socket to > forcibly bind to a port in use by another socket. The second socket > calls setsockopt with the optname parameter set to SO_REUSEADDR and > the optval parameter set to a boolean value of TRUE before calling > bind on the same port as the original > socket. Once the second socket has successfully bound, the behavior for all > sockets bound to that port is indeterminate. For example, if all of the > sockets > on the same port provide TCP service, any incoming TCP connection requests > over > the port cannot be guaranteed to be handled by the correct socket — the > behavior is non-deterministic. “ > Whereas on Linux, "SO_REUSEADDR socket option, which explicitly allows > a process to bind to a > port which remains in TIME_WAIT (it still only allows a single process > to be bound to that > port). The bind function fails to operate properly when the server > terminates and we try to restart it immediately. Normally, the implementation > of TCP will prevent us from binding the same address until a timeout expires, > which is usually on the order of several minutes. Luckily, the > SO_REUSEADDR socket option allows us to bypass this." > Is it expected behaviour?
I ran into this in an unrelated project years ago. If memory serves, Windows' SO_REUSEADDR is broken by design. Luckily, its bind() seems to be broken as well: it seems to succeed while the port is in state TIME_WAIT by default. My solution then was not to set SO_REUSEADDR on Windows. http://tomayko.com/writings/that-dilbert-cartoon