Java Socket.close()在Socket.connect()期间无效

Java Socket.close()在Socket.connect()期间无效,java,multithreading,sockets,Java,Multithreading,Sockets,在Windows上使用默认套接字实现时,我找不到任何有效的方法来停止socket.connect()。建议Thread.interrupt()将不起作用,但Socket.close()将起作用。然而,在我的试验中,后者也不起作用 我的目标是快速、干净地终止应用程序(即,在套接字终止后需要完成清理工作)。我不想在Socket.connect()中使用超时,因为可以在合理的超时过期之前终止进程 import java.net.InetSocketAddress; import java.net.So

在Windows上使用默认套接字实现时,我找不到任何有效的方法来停止
socket.connect()
。建议
Thread.interrupt()
将不起作用,但
Socket.close()将起作用。然而,在我的试验中,后者也不起作用

我的目标是快速、干净地终止应用程序(即,在套接字终止后需要完成清理工作)。我不想在
Socket.connect()
中使用超时,因为可以在合理的超时过期之前终止进程

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);
    }
}
输出:

/10.1.1.1:11
Closing...
Closed
Interrupted
(A few seconds later)
Exception in thread "main" java.net.SocketException: Socket operation on nonsocket: connect

您分叉线程,然后主线程尝试连接到远程服务器。套接字尚未连接,因此我怀疑
s.close()
对未连接的套接字没有任何作用。很难看出INET套接字实现在这里做了什么<代码>t.中断()无法工作,因为连接(…)
不可中断

您可以使用NIO
SocketChannel.connect(…)
,它看起来是可中断的。可能是这样的:

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

不确定这是否会有帮助。

是的,我也这么想。但是,必须有一些替代实现可以被终止……查看文档,似乎SocketCannel的主要优势之一是能够停止
connect()
。我稍后会尝试一下,但我相信这是解决办法。谢谢实际上,API似乎要求您使用选择器来真正实现易于中断的行为(即,如果通道是非阻塞的,那么您需要一个选择器来知道它何时实际连接)。否则,必须在
SocketChannel.finishConnect()上旋转。暂时取消标记作为答案,看看其他人是否有更好的选择(尽管可能性不大:[)。为什么要在连接期间关闭套接字?如果要强制连接超时,可以使用API来执行。@EJP这是一个业务应用程序,其中每个操作都需要是原子的。但是,它在tomcat上运行,其中stop命令有一个超时。如果tomcat关闭时,套接字恰好在connect调用中,我们发现套接字线程中的清理代码不运行。因此,在建立连接之前,不应该执行任何需要清理的操作。