2016-11-28 1 views
4

Socket 및 ServerSocket 포트 사용법에 대해 혼란스러워합니다.클라이언트를 수락 한 후 Java ServerSocket이 동일한 로컬 포트에 바인딩 된 새 소켓을 얻는 방법은 무엇입니까?

소켓은 무엇인가 : Oracle's java tutorial about sockets는 다음 말한다?

일반적으로 서버는 특정 컴퓨터에서 실행되며 특정 포트 번호에 바인딩 된 소켓이 있습니다. 서버는 클라이언트가 연결 요청을하기 위해 소켓을 청취하기 만하면됩니다. 클라이언트 측 : 클라이언트는 서버가 실행중인 시스템의 호스트 이름과 서버가 수신 대기중인 포트 번호를 알고 있습니다. 연결 요청을하기 위해 클라이언트는 서버의 시스템과 포트에서 서버와의 랑데뷰를 시도합니다. 클라이언트는 서버에 자신을 식별 시켜서이 연결 중에 사용할 로컬 포트 ​​번호에 바인드해야합니다. 일반적으로 시스템에 의해 할당됩니다.

모든 것이 잘되면 서버는 연결을 수락합니다. 수락시 서버는 동일한 로컬 포트 ​​ 에 바인드 된 새 소켓을 가져오고 클라이언트의 주소와 포트로 설정된 원격 끝점을 갖습니다. 연결된 클라이언트 의 필요를 돌보는 동안 연결 요청에 대해 원래 소켓을 계속 수신 할 수 있도록 새 소켓이 필요합니다.

클라이언트 쪽에서 연결이 수락되면 소켓이 성공적으로 만들어지고 클라이언트는 소켓을 사용하여 서버와 통신 할 수 있습니다. 이제 클라이언트와 서버는 소켓에 쓰거나 소켓에서 읽음으로써 통신 할 수 있습니다.

테스트를 위해 다음 코드를 시도했습니다. 그러나 그것은 예외를 던집니다.

try { 
    ServerSocket serverSocket = new ServerSocket(8080); 

    Socket socket = serverSocket.accept(); 

    // This prints 8080 
    System.out.println("Local port of accepted socket : " + socket.getLocalPort()); 

    // But this throws java.net.BindException: Address already in use: JVM_Bind 
    Socket myClientSocket = new Socket("www.google.com", 80, null, 8080); 

} catch (Exception e) { 
    e.printStackTrace(); 
} 

제 질문은 분명합니다. serverSocket.accept()에서 반환 된 소켓은 동일한 로컬 포트 ​​(8080)를 사용할 수 있지만 왜 내가 만든 소켓을 사용할 수 없습니까?

+0

그들이 설계 한 방식이기 때문입니다. 인용하고있는 것에 대해 명확히 기재하십시오. – EJP

답변

-1

서버와 클라이언트가 동일한 로컬 포트를 사용하여 통신하고 있습니다. 서버 소켓을 만들었 으면 "8080 포트에서 수신 대기해야합니다. 괜찮아. 서버 소켓과 통신하려는 모든 사용자는 이러한 포트를 사용해야합니다.

하지만 바로 아래 포트 80을 사용하여 Google 사이트에 연결하는 클라이언트 소켓을 만들고 (Google은 해당 포트에서 수신 대기하고 있음) 마지막 인수에서이 소켓이 로컬 포트를 사용해야한다고 말하고 있습니다 8080 연결을 설정하십시오. 한 번에 하나의 연결 만 포트를 사용할 수 있으므로 java.net.BindException이 발생합니다. 서버와 클라이언트 모두 8080을 사용하고 있습니다.

제안 사항 ...

Socket myClientSocket = new Socket("www.google.com", 80); 

또는

Socket myClientSocket = new Socket("www.google.com", 80, null, 58080); 
+0

OP가 'accept'서버로 생성 된 포트가 '8080'의 로컬 포트를 가질 때 * 왜 * 이런 일이 발생하는지 묻습니다. – RealSkeptic

+0

"한 번에 하나의 프로세스 만 포트를 사용할 수 있기 때문에 java.net.BindException이 발생합니다."라고 대답했을 때 대답했습니다. 그는 서버와 클라이언트 모두에 8080 로컬 포트 ​​(인바운드 및 아웃 바운드)를 사용합니다. – RLM

+0

@RaphaelMoita이 코드는 모두 동일한 프로세스에서 실행됩니다. 너는 그 질문에 대답하지 않았다. – EJP

1

유지하려면 : (항상 다른 프로세스와 같은 문제를 피하기 위해 높은 번호를)하면 소켓 클라이언트 생성자에서 마지막 두 개의 인수를, 또는 당신에게 로컬 클라이언트 포트를 변경 그것은 간단합니다. 수신 TCP 소켓은 이미 포트에 명시 적으로 바인딩되어 있으므로 두 소켓 모두 INADDR_ANY가 아닌 다른 IP 주소에도 명시 적으로 바인딩되어 있지 않으면 두 번째 TCP 소켓을 동일한 포트에 명시 적으로 바인딩 할 수 없습니다.

허용되는 소켓은 명시 적 '바인드'프로세스를 거치지 않습니다. 그들은 로컬 IP 주소와 포트를 자동으로 획득합니다. 바인딩없이 연결하면 아웃 바운드 소켓도 마찬가지입니다.

+0

@RaphaelMoita 귀하의 요점은 나를 벗어납니다. – EJP

관련 문제