-4
아래 프로그램을 실행할 때 bind()
및 connect()
메서드가 즉시 예외를 throw하는 이유는 무엇입니까?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 + + 구현과 느낌을 오픈 JDK 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를 차단하는 이유는 매개 변수를 연결하는 방법입니다? 왜 블레 킹 4s ?? – Gaohongyan
컴퓨터에서 테스트 할 수 있지만 문제가 서버에 연결되어 있지 않습니다. BIND() 실행이 비정상적으로 나타나면 bind() 메서드를 실행하지 않으면 connect() 메서드 블록이 4 초가 걸리므로 기본 소스가 모양을 보았고 이해할 수 없으므로 문의하십시오. – Gaohongyan
귀하의 질문에 답변했습니다. 이미 내 대답을 이해하지 못한다면 나는 더 이상 당신을 도울 수 없습니다. – EJP