2

誰でもjava.net.ConnectExceptionを説明できますか:接続がタイムアウトしました

Caused by: java.net.ConnectException: Connection timed out 
    at java.net.PlainSocketImpl.socketConnect(Native Method) 
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:337) 
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:198) 
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:180) 
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:391) 
    at java.net.Socket.connect(Socket.java:579) 
    at sun.reflect.GeneratedMethodAccessor11.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at net.sourceforge.jtds.jdbc.SharedSocket.createSocketForJDBC3(SharedSocket.java:289) 
    at net.sourceforge.jtds.jdbc.SharedSocket.(SharedSocket.java:250) 
    at net.sourceforge.jtds.jdbc.ConnectionJDBC2.(ConnectionJDBC2.java:297)
4

3 に答える 3

1

SQL サーバーに ping を実行できる場合、これは SQL サーバー インスタンスの TCP/IP 構成に問題がある可能性があります。

TCP/IP を有効にする方法については、この質問を参照してください。また、Microsoft のこの記事とこの記事も参照してください。

  1. SQL Server 構成マネージャーを起動します。[スタート] をクリックし、[すべてのプログラム] をポイントして、[Microsoft SQL Server] をクリックします。[構成ツール] をクリックし、[SQL Server 構成マネージャー] をクリックします。
  2. SQL Server 構成マネージャーのコンソール ウィンドウで、[SQL Server ネットワーク構成] を展開します。
  3. コンソール ウィンドウで、[プロトコル] をクリックします。
  4. 詳細ウィンドウで、[TCP/IP] を右クリックし、[有効にする] をクリックします。
  5. コンソール ウィンドウで、[SQL Server サービス] をクリックします。
  6. 詳細ウィンドウで、SQL Server () を右クリックし、[再起動] をクリックして、SQL Server サービスを停止して再起動します。
于 2013-01-08T11:59:12.593 に答える
1

これは、ドライバーがそのポートでその IP への接続を開こうとしたが、そのポートでリッスンしている人がいなかったため、誰も応答しなかったため、「接続がタイムアウトしました」というメッセージが表示されたことを意味します。

Arunn P Johnyが提案したように、コマンドラインを開いて実行すると

telnet localhost 4545

そしてそれはこのように応答します

Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused

これは、誰も聞いていないことを意味します。たとえば、そのポートでソケット (データベース接続) を開こうとすると、接続タイムアウト例外が発生します。(ポート 4545 が選択されたのは、コンピューターでリッスンしているものがないためです)

それが何か他のもので応答する場合

telnet localhost 3306

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

これは、ポートが開いていて、例外がスローされないことを意味します。(私のコンピューターの 3306 でリッスンしている MySQL があります)。

ほとんどの場合、データベース接続文字列(参照についてはこちらを参照) の IP とポートが間違っています。たとえば、データベースがリッスンしていないポートに設定されています。

この回答とHTTPエラー408リクエストタイムアウトの説明を参照してください(同じエラーです)。

編集:

私は最初に間違った答えを出しました (EJP が指摘したように)。接続の確立中に両方のエラーが TCP レベルで発生します。

  • Connection refused指定されたポートでリッスンしている人がいないことを意味します
  • Connection timeout接続を確立できなかったか、または EJP で述べられているように、接続試行がタイムアウトしたことを意味します。

Java に次の行があるとします。最終的に JDBC ドライバーは、ある時点でこれを (次のように) 実行します。

Socket s = new Socket(IP,PORT);

この行が実行される前に、(TCP) 接続は閉じられます。この行が実行され、例外がスローされなかった後、接続が確立されます (コンストラクターの apidoc に記載されているとおり)。この行が実行されている間、これが実際に発生します ( TCP スリーウェイ ハンドシェイクと呼ばれます)。

TCP スリーウェイ ハンドシェイク

考えられる 2 つの状況を確認してみましょう。

まず、IP に到達可能であるとしましょう (たとえばping IP、コマンド ラインからコンソールへの応答時間の出力が開始されます) が、ポートでリッスンしているプロセスはありません。スリーウェイ ハンドシェイクは引き出されたときに発生しますが、接続が確立されるとすぐに、サーバーはそのポートでリッスンしているプロセスを見つけられず、すぐに接続のクローズを開始しConnection refusedます。スローされます。

これは、この例外の唯一の可能な結果です

ここで、IP に到達できないと仮定しましょう。クライアントは接続要求を送信しますが、接続許可を受け取ることはありません。一定時間 ( timeout ) が経過すると、Connection timeoutがスローされます。次のコードを検討してください。

    String reachableIP = "127.0.0.1";
    String unreachableIP = "10.192.0.1";
    int connTimeout = 1000;
    long duration = 0;        
    try {
        duration = System.currentTimeMillis();            
        new Socket().connect(new InetSocketAddress(unreachableIP, 3306), connTimeout);
    }
    catch (Exception e) {
        duration = System.currentTimeMillis() - duration;           
        System.out.println("connect attempt duration measured in ms:" + duration);
        System.out.println(e.getMessage());
    }

出力:

connect attempt duration measured in ms:1009
connect timed out

これはconnect メソッドの apidoc にも記載されています。そのため、宛先 IP に到達できない場合、この例外がスローされます。ただし、ネットワーク上のコンピュータに到達できない理由は数多くあります。最初に頭に浮かぶのは、ホストがオフになっていること、または EJP のコメントを言い換えることです。

バックログ キューがいっぱいになったり、ネットワーク接続の問題が原因でこの例外が発生したりするなど、さまざまな原因が考えられます。

于 2013-01-08T11:07:31.403 に答える