ホームページ  >  記事  >  Java  >  Javaでソケットのタイムアウトを設定する

Javaでソケットのタイムアウトを設定する

尚
転載
2019-11-28 17:17:055253ブラウズ

Javaでソケットのタイムアウトを設定する

Java でソケットのタイムアウトを設定するには、主に 2 つの方法があります。見てみましょう: (推奨: java ビデオ チュートリアル )

方法 1:

Socket s=new Socket(); 
s.connect(new InetSocketAddress(host,port),10000);

方法 2:

Socket s=new Socket("127.0.0.1",8080);
s.setSoTimeout(10000);

では、これら 2 つの方法で設定されたタイムアウトは何を意味するのでしょうか?どのような違いがありますか?

最初の方法

まず最初の方法を見て、テストしてみましょう:

メイン メソッドでは、Socket Connect を作成します。

ip: 29.212.19.201、port: 2132

public static void main(String[] args) {
    Socket socket = new Socket();
    SocketAddress endpoint = new InetSocketAddress("29.212.19.201", 2132);
    long timeMillis = System.currentTimeMillis();
    try {
      socket.connect(endpoint, 10000);
    } catch (IOException e) {
      e.printStackTrace();
    }
    System.out.println(System.currentTimeMillis()-timeMillis);
    System.out.println("end");
  }

このコードを実行すると、10 秒前まではコンソールに情報が出力されず、10 秒後に次の情報が出力されます。

10002
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.wakling.cn.SocketSever.main(SocketSever.java:33)
end

29.212.19.201:2132 に接続しようとしたときに、10 秒間接続に失敗したため、java.net.SocketTimeoutException: connect timed out 例外が報告されたことがわかります。

上記の IP は不明な IP であることを説明します。つまり、私の IP は現在のネットワーク環境ではこの IP にアクセスできないため、ソケットはタイムアウトになるまでこの IP への接続を試行し続けます。 IP がローカル 127.0.0.1 と未知のポートなどの既知の IP である場合、このソケット接続はすぐにエラーを報告します。

さらに、接続タイムアウトが設定されていない場合、ソケットのデフォルトの接続タイムアウトは約 21 秒です (3 回テストされ、すべて 21020 ミリ秒)。以下は、接続タイムアウトを設定しないコードです:

Socket socket = new Socket("29.212.19.201", 2132);

2 番目の方法

次に、2 番目の方法を見てみましょう。このシナリオをシミュレートするためのソケット サービスとクライアントのセットを作成します。

クライアントに setSoTimeout を 10 秒に設定させました。サーバー コードはクライアント リクエスト情報を取得した後、クライアント リクエストを処理して応答を返す前に 10 秒スリープします。

効果を見てみましょう。キー コードは次のとおりです:

//服务端
System.out.println("进入休眠,10s后醒来");
Thread.sleep(10000);
System.out.println("休眠结束");
//返回响应
OutputStream outputStream = socket.getOutputStream();// 获取一个输出流,向服务端发送信息
PrintWriter printWriter = new PrintWriter(outputStream);// 将输出流包装成打印流
printWriter.print("你好,服务端已接收到您的信息");
printWriter.flush();

//客户端
Socket socket = new Socket("127.0.0.1",2132);
socket.setSoTimeout(10000);//read的超时时间

実行後、クライアントの出力を待ちます。10 秒後、クライアント コンソールに次の情報が出力されます:

java.net.SocketTimeoutException: Read timed out
  at java.net.SocketInputStream.socketRead0(Native Method)
  at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
  at java.net.SocketInputStream.read(SocketInputStream.java:171)
  at java.net.SocketInputStream.read(SocketInputStream.java:141)
  at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
  at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
  at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
  at java.io.InputStreamReader.read(InputStreamReader.java:184)
  at java.io.BufferedReader.fill(BufferedReader.java:161)
  at java.io.BufferedReader.readLine(BufferedReader.java:324)
  at java.io.BufferedReader.readLine(BufferedReader.java:389)
  at com.wakling.cn.SocketClient.main(SocketClient.java:36)
10020
end

10s here その後、クライアントがエラーを報告しました java.net.SocketTimeoutException: Read timed out. 通常の出力については、クライアント コンソール情報を確認してください。クライアントがタイムアウトを報告しても、サーバーはダウンし続けますが、クライアントは、サーバーによって送信されたメッセージを 10 秒経過しても受信していません。

さらに、テストでは、サーバーが 500 秒などの長時間スリープすることが判明しました。クライアントが setSoTimeout を設定しない場合、デフォルトのタイムアウトは 120 秒です。

違いと重要性

両者の意味と違いについてお話しましょう。

メソッド 1 は、クライアントとサーバー間の接続のタイムアウト時間です。つまり、接続が 10 秒以内に確立できない場合、java.net.SocketTimeoutException: connect timed out 接続タイムアウト例外が発生します。報告。現時点では、この 2 つは接続を確立しておらず、ましてやサーバーがクライアントからメッセージを受信して​​いません。

方法 2 では、inputStream.read() メソッドのブロック時間、つまり、クライアントがリクエストを送信した後、サーバーがレスポンスを返すまでの待ち時間を設定します。この時間を超えると、原因 java.net.SocketTimeoutException: 読み取りタイムアウトが異常です。このとき、両者は正常に接続を確立し、サーバーはクライアントのリクエストを受け取ります。

タイムアウトを制御する 2 つの方法は、焦点が異なります。電話をかけるのと同じように、方法 1 では 10 秒間電話をかけます。電話に応答しない場合は電話を切ります。方法 2 は次のとおりです。電話がつながってから 10 秒間待機します。数秒間話さないと電話を切ります。10 秒経過すると、話さなくても聞きません。

Java についてさらに詳しく知りたい場合は、Java 基本チュートリアル 列に注目してください。

以上がJavaでソケットのタイムアウトを設定するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。