I write a simple go program which runs on windows and tests whether the remote port is active:
package main
import (
"fmt"
"net"
)
func main(){
conn, err := net.Dial("tcp", "192.168.23.191:3403")
if err != nil {
fmt.Println(err)
} else {
conn.Close()
}
}
Now, the remote port is closed. I run it first time, and the error is:
dial tcp 192.168.23.191:3403: ConnectEx tcp: The remote computer refused the network connection.
Then I continue to run it, the error is changed to:
dial tcp 192.168.23.191:3403: ConnectEx tcp: The semaphore timeout period has expired.
Why the Dial returns "ConnectEx tcp: The semaphore timeout period has expired."? And what is the meaning of this error?
The call to net.Dial()
has a timeout which expired.
As seen here, the Dialer
struct has a Timeout
field which defines the maximum amount of time that a Dial()
will wait for a connect to complete.
net.Dial
(with some intermediate functions) ends up calling ConnectEx
, a Windows specific extension to BSD Sockets.
If the connection cannot be established (Windows conforms to RFC 1122 Section 4.2.3.5 and tries multiple times) ConnectEx fails with ERROR_SEM_TIMEOUT
(AFAIK that isn't officially documented, one would expect an error like WSAETIMEDOUT
).
So that error means that the port is closed.
On Windows 8 and newer Versions of Windows it is possible to change the connections settings for a single socket, if you want to do this in Go you have to do the version check and calls for yourself.