Skip to content
Advertisement

Linux Socket timeout works on WSL, but not on Ubuntu

I try to run a TCP client without a server. The idea is simply to periodically try to connect. For this, the client tries to connect to port 1500 on localhost.

Piece of code:

JavaScript

I’ve set it up in Ubuntu 18.04 on WSL. There, the code waits on select for the defined timeout of 2 seconds and returns appropriate return values. (0 on timeout, 1 on connect). The return value of connect is -1 on WSL and VMware. In Ubuntu 18 (VMware) there is no pause in that line. In any case, even without any server listening on that port, I get immediately a return value of 1.

Why is there this difference?

There is a similar behavior later on in that code:

JavaScript

Here, in WSL the recv takes up to 2 seconds, while waiting for any incoming data. (But only if the aforementioned block (connect, select) indicates a valid connection) In VMware I directly get the feedback. (even without connection)

Does it simply work on WSL by chance?

The argument contains the server IP and is 127.0.0.1. lsof shows no connection.


Update 2020-11-18

Here’s the full code as requested by Bodo

JavaScript

In WSL the output is

JavaScript

then nothing for 2 seconds afterwards

JavaScript

and again nothing for 2 seconds …

Output in VMware

JavaScript

Where no timeout is fulfilled.

The idea of timeout has been to try to connect on a regular basis, but not as fast as possible.

Advertisement

Answer

Obviously there is something wrong when errno = 111 (ECONNREFUSED) is followed by Connection with server (127.0.0.1) established.

When connect returns -1 and errno is NOT EINPROGRESS you should not use selectand getsockopt(...SO_ERROR...). According to https://man7.org/linux/man-pages/man2/connect.2.html, this is only documented for EINPROGRESS.

Both on real Linux and WSL you get errno = 111 (ECONNREFUSED) after a failed connect. I consider the timeout in WSL wrong as the error (conection refused) was already reported, so it does not make sense to wait for a result. But as the behavior is not specified, it may be implementation dependent.

If you want to have a delay before the next connection attempt, you should not use select but for example sleep followed by repeating the loop.

I suggest something like this:

JavaScript
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement