Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Socket.close() have no effect during Socket.connect()

Using the default socket implementation on Windows, I was not able to find any effective method to stop Socket.connect(). This answer suggests Thread.interrupt() will not work, but Socket.close() will. However, in my trial, the latter didn't work either.

My goal is to terminate the application quickly and cleanly (i.e. clean up work needs to be done after the socket termination). I do not want to use the timeout in Socket.connect() because the process can be killed before a reasonable timeout has expired.

import java.net.InetSocketAddress;
import java.net.Socket;


public class ComTest {
    static Socket s;
    static Thread t;

    public static void main(String[] args) throws Exception {
        s = new Socket();
        InetSocketAddress addr = new InetSocketAddress("10.1.1.1", 11);
        p(addr);
        t = Thread.currentThread();
        (new Thread() {
            @Override
            public void run() {
                try {
                    sleep(4000);
                    p("Closing...");
                    s.close();
                    p("Closed");
                    t.interrupt();
                    p("Interrupted");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
        s.connect(addr);
    }

    static void p(Object o) {
        System.out.println(o);
    }
}

Output:

/10.1.1.1:11
Closing...
Closed
Interrupted
(A few seconds later)
Exception in thread "main" java.net.SocketException: Socket operation on nonsocket: connect
like image 958
billc.cn Avatar asked Jan 25 '13 19:01

billc.cn


1 Answers

You fork the thread and then the main thread is trying to make the connection to the remote server. The socket is not yet connected so I suspect s.close() does nothing on a socket that is not connected. It's hard to see what the INET socket implementation does here. t.interrupt(); won't work because the connect(...) is not interruptible.

You could use the NIO SocketChannel.connect(...) which looks to be interruptible. Maybe something like:

SocketChannel sc = SocketChannel.open();
// this can be interrupted
boolean connected = sc.connect(t.address);

Not sure if that would help though.

like image 101
Gray Avatar answered Nov 07 '22 06:11

Gray