-4
以下のプログラムを実行すると、bind()
およびconnect()
のメソッドはただちに例外をスローします。Javaソケット:bind()およびconnect()メソッドの問題
bind()
メソッドを使用しない場合、connect()
メソッドは4秒間実行をブロックしています。理由は何でしょうか?
package test1;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
public class Test73 {
public static void main(String[] args) throws IOException {
long beginTime = 0;
try {
Socket socket = new Socket();
System.out.println(socket.getPort());
System.out.println(socket.getLocalPort());
// socket.bind(new InetSocketAddress("localhost", 7777));
System.out.println(socket.getPort());
System.out.println(socket.getLocalPort());
beginTime = System.currentTimeMillis();
socket.connect(new InetSocketAddress("1.1.1.1", 8888), 4000);
System.out.println(socket.getPort());
System.out.println(socket.getLocalPort());
socket.close();
System.out.println("client end!");
} catch (Exception e) {
long endTime = System.currentTimeMillis();
System.out.println(endTime - beginTime);
e.printStackTrace();
}
}
}
下のコードは、ネイティブソースコードです、それは私が基礎となるC + +の実装と感じるOpenJDKのsource.Thisの問題なので、下のソースコードが掲載されています!
JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_waitForConnect
(JNIEnv *env, jclass clazz, jint fd, jint timeout) {
int rv, retry;
int optlen = sizeof(rv);
fd_set wr, ex;
struct timeval t;
FD_ZERO(&wr);
FD_ZERO(&ex);
FD_SET(fd, &wr);
FD_SET(fd, &ex);
t.tv_sec = timeout/1000;
t.tv_usec = (timeout % 1000) * 1000;
/*
* Wait for timeout, connection established or
* connection failed.
*/
rv = select(fd+1, 0, &wr, &ex, &t);
/*
* Timeout before connection is established/failed so
* we throw exception and shutdown input/output to prevent
* socket from being used.
* The socket should be closed immediately by the caller.
*/
if (rv == 0) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
"connect timed out");
shutdown(fd, SD_BOTH);
return;
}
/*
* Socket is writable or error occurred. On some Windows editions
* the socket will appear writable when the connect fails so we
* check for error rather than writable.
*/
if (!FD_ISSET(fd, &ex)) {
return; /* connection established */
}
/*
* Connection failed. The logic here is designed to work around
* bug on Windows NT whereby using getsockopt to obtain the
* last error (SO_ERROR) indicates there is no error. The workaround
* on NT is to allow winsock to be scheduled and this is done by
* yielding and retrying. As yielding is problematic in heavy
* load conditions we attempt up to 3 times to get the error reason.
*/
for (retry=0; retry<3; retry++) {
NET_GetSockOpt(fd, SOL_SOCKET, SO_ERROR,
(char*)&rv, &optlen);
if (rv) {
break;
}
Sleep(0);
}
if (rv == 0) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Unable to establish connection");
} else {
NET_ThrowNew(env, rv, "connect");
}
}
EJP〜ありがとうございます〜ですが質問は接続方法タイムアウトパラメータです、なぜ4sをブロックしますか?なぜ駄目なの? – Gaohongyan
私の問題はサーバーに接続されていない、コンピュータ上でテストすることができます。 bind()メソッドを実行しないとconnect()メソッドブロックが4秒間ブロックされ、BIND()の実行がすぐに異常なように見える場合は、ネイティブソースが一見を見ています。 – Gaohongyan
私はあなたの質問に答えました。あなたの答えがすでに書かれているように理解できない場合、私はあなたをさらに助けることはできません。 – EJP