Search code examples
javasocketssocket-timeout-exception

Exception "java.net.ConnectException: Connection timed out: connect" is thrown before specified timeout


I have following code:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;

public class ScoketTimeoutMain
{
    public static void main( String[] args )
    {

        Socket socket = new Socket();
        InetSocketAddress address = new InetSocketAddress( "example.com", 81 );
        final long l = System.currentTimeMillis();
        try
        {
            socket.connect( address, 60000 );
        }
        catch( IOException aE )
        {
            aE.printStackTrace();
            System.out.println( System.currentTimeMillis() - l );
        }
    }
}

Connection timeout is thrown after about 21 seconds:

java.net.ConnectException: Connection timed out: connect
    at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
    at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at com.kulig.ScoketTimeoutMain.main(ScoketTimeoutMain.java:17)
21004

I do not understand why exception is thrown after 21 seconds instead of 60 seconds.

===EDIT===

If i set timeout smaller than 21 seconds then it works properly. E.g.:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;

public class ScoketTimeoutMain
{
    public static void main( String[] args )
    {

        Socket socket = new Socket();
        InetSocketAddress address = new InetSocketAddress( "example.com", 81 );
        final long l = System.currentTimeMillis();
        try
        {
            socket.connect( address, 2000 );
        }
        catch( IOException aE )
        {
            aE.printStackTrace();
            System.out.println( System.currentTimeMillis() - l );
        }
    }
}

java.net.SocketTimeoutException: connect timed out
    at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
    at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at com.kulig.ScoketTimeoutMain.main(ScoketTimeoutMain.java:17)
2002

So some another timeout occurs. I have no idea what can cause it and how to set this other timeout.


Solution

  • I got the exact same 21 seconds (21007). Searching the internet, the 21 seconds timeout is not that rare. Based on this hotfix, I changed the Max SYN Retransmissions parameter of TCP and got the 60 seconds timeout:

    netsh interface tcp set global MaxSynRetransmissions=5
    

    Default value is 2.