6

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
4

1 に答える 1

4

スレッドをフォークすると、メインスレッドがリモートサーバーへの接続を試みます。ソケットはまだ接続されていないので、接続されてs.close()いないソケットでは何もしないと思います。ここでINETソケットの実装が何をするのかを理解するのは難しいです。 は中断できないt.interrupt();ため、機能しません。connect(...)

SocketChannel.connect(...)割り込み可能に見えるNIOを使用できます。多分次のようなものです:

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

しかし、それが役立つかどうかはわかりません。

于 2013-01-25T19:35:36.710 に答える