2012-06-17 4 views
2

이 백서에 설명 된 것처럼 NAT의 TCP 홀 펀칭을 프로토 타입 화하려고합니다. http://www.brynosaurus.com/pub/net/p2pnat/.연결을 닫은 후 로컬 포트를 통해 연결할 수 없습니다.

특정 로컬 포트에서 서버에 대한 연결을 시도하는이 간단한 코드가 있습니다. NAT가 동일한 NAT 매핑에 대한 연결을 모두 매핑하는지 공용 서버에서 관찰하려고합니다.

int localPort = getFreeLocalPort(); 

    while (true) { 

     Socket connection = new Socket(_publicServerHost,_publicServerPort, 
       getLocalSocketAddress(), localPort); 

     connection.setReuseAddress(true); 

     connection.close(); 

    } 

처음 연결할 때 잘됩니다.

홀 펀칭을 위해 선택

로컬 포트가 : 65,416이

2012-06-17 15 : 55 : 그러나 두번째 시도는 예외가 발생 21545 오류 - 이미 사용중인 주소 : 연결을

2012-06 -17 15 : 55 : 25,175 디버그 - 세부 사항 : java.net.BindException : 주소가 이미 사용 중입니다 : connect java.net.PlainSocketImpl.socketConnect (native method) ~ [na : 1.6.0_24] at java.net에서 을 연결하십시오. .PlainSocketImpl.doConnect (PlainSocketImpl.java:351) ~ [na : 1.6.0_24] at java.net.PlainSocketImpl.connectToAddress (PlainSocketImpl.java:213) ~ [na : 1.6.0_24]java.net.SocketSocketImpl.connect (SocksSocketImpl.java:366) ~ [na : 1.6.0_24] at java.net.SocksSocketImpl.connect (SocksSocketImpl.java:366) ~ [na : 1.6.0_24] at에있는 java.net.PlainSocketImpl.connect (PlainSocketImpl.java:200)에서java.net.Socket.connect (Socket.java:529) ~ [na : 1.6.0_24] at java.net.Socket.connect (Socket.java:478) ~ [na : 1.6.0_24] at java. net.Socket (Socket.java:375) ~ [na : 1.6.0_24] at java.net.Socket (Socket.java:249) ~ [na : 1.6.0_24]

답변

1

connection.setSoLinger(true, 0);을 직접 추가하십시오. before connection.close() ;. 그래서 같이

는 :

connection.setSoLinger(true, 0); 
connection.close(); 

이 소켓을 해제 할 수있는 OS를 강제로.

+0

보류중인 송신 데이터를 버립니다. 권장하지 않습니다. – EJP

+0

if (connection.isConnected() && connection.isBound()) { connection.setSoLinger (true, 0); connection.close(); } 하지만 java.net.SocketException이 발생합니다. 소켓이 닫힙니다. – pkrish

+0

@pkrish'Socket.isConnected()'는 소켓 연결 여부 만 알려줍니다. 'Socket.isBound()'는 당신이 소켓을 묶었는지 여부만을 알려준다. 어느 쪽도 소켓을 닫았는지 또는 피어가 그렇게했을 때 그 점에 대해서도 알려주지 않습니다. 어쨌든 당신은 모든 것을 가지고 틀린 나무를 완전히 짖고 있습니다. 내 대답을 보라. – EJP

0

어떤 이유로 로컬 포트가 선택 되었습니까? Obviosuly 소리가 하나. 시스템에서 0을 지정하고 개방 후 실제 값인 소켓에서 가져 오는 것이 좋을 것입니다.

+0

getFreeLocalPort() 메서드는 사용 가능한 로컬 포트를 가져옵니다.ServerSocket 서버 = 새로운 ServerSocket (0); int port = server.getLocalPort(); – pkrish

+0

@pkrish Err하지만 TIME_WAIT에있는 포트를 선택하기 때문에 무료 로컬 포트를 얻지 못합니다. 설명 된 기술은 100 % 신뢰도를 가진 무료 로컬 포트를 얻을 것입니다. – EJP

+0

같은 로컬 포트를 통해 여러 개의 연결을 만들고 싶습니다. TIME_WAIT 상태의 포트입니다. connection.setReuseAddress (true); 네가 그렇게하도록 내버려 둔다. 이렇게하는 이유는 TCP 홀 펀칭을 달성하기 위해서입니다. 제가 링크 한 논문 (4.1 절)을 읽으면 좀 더 자세히 설명합니다. – pkrish

0

문제가 해결 되었습니까? 포트를 할당하기 전에 setReuseAddress()를 호출해야합니다.

Socket connection = new Socket(); 
connection.setReuseAddress(true); 
connection.bind(...); 
관련 문제