2011-02-09 6 views
21

기계는 RHEL 5.3 (커널 2.6.18)입니다.어떻게 동일한 포트에 TCP 연결을 다시 할 수 있습니까?

몇 번 나는 내 응용 프로그램 연결이 NETSTAT에 로컬 주소해외 주소이 동일 설립 TCP 연결을 확인할 수 있습니다.

Here 같은 문제가 다른 사람에게도보고되었습니다.

증상은 로컬에서 실행되는 서버의 포트 -X 포트에 링크 - 클라이언트 연결에서 설명한 것과 같습니다. 얼마 후 netstat은 클라이언트가 연결되어 있음을 보여줍니다. 127.0.0.1:X에서 127.0.0.1:X

어떻게 가능합니까?

편집 01

동시 개방 문제 (감사 Hasturkun에 많은)의 원인이된다. classical TCP state diagram에서 SYN_SENT 상태에서 SYNC_RECEIVED로 넘어갑니다.

+0

증상은 로컬에서 실행중인 서버의 포트 X 포트에 대한 링크 - 클라이언트 연결에 설명 된 것과 같습니다. 얼마 후 netstat은 클라이언트가 127.0.0.1:X에서 127.0.0.1:X – dimba

답변

17

이것은 TCP 동시 연결 (on this post to LKML을 참조하십시오. here 참조)이 원인 일 수 있습니다.

동적 로컬 포트 ​​범위 (/proc/sys/net/ipv4/ip_local_port_range에서 볼 수 있음) 내의 포트에 연결하려고 시도하는 프로그램이 서버가 해당 포트에서 수신 대기하지 않는 동안 계속 반복 될 수 있습니다.

충분히 많은 수의 시도에서 연결에 사용되는 소켓은 이전에 언급 한 동시 연결로 인해 성공한 동일한 포트에 연결될 수 있습니다. 이제 마술처럼 클라이언트가 연결되었습니다.

+0

+1이 내 문제의 내 원인이 될 수 있습니다. – dimba

+0

사실 내 클라이언트는 서버가 다운 된 경우 지속적으로 서버에 연결을 시도합니다. 이제 어떻게 그런 상황을 막을 수 있을까요? 서버가/proc/sys/net/ipv4/ip_local_port_range 범위가 아닌 포트를 사용해야한다는 것을 의미합니까? – dimba

+0

@ dimba : 예, 서버가이 범위의 최하위보다 낮은 포트를 수신하면이 문제를 방지 할 수 있습니다. – Hasturkun

12

TCP 연결은이 튜플 (local address, local port #, foreign address, foreign port #)에 의해 고유하게 식별됩니다. local addressforeign address이라는 요구 사항이 없으며 포트 번호가 다를 수도 있습니다 (상당히 이상 할지라도). 그러나 주어진 튜플에 대해 동일한 값을 갖는 최대 하나의 TCP 연결이 있습니다.

컴퓨터가 자체에 연결되면 로컬 주소이고 외부 주소는 거의 항상 동일합니다. 결국 '로컬'쪽과 '외부'쪽은 실제로 같은 컴퓨터입니다. 사실이 경우 컴퓨터에서 '로컬'및 '외부'주소가 같지만 포트 번호가 반대 인 두 연결이 표시되어야합니다. 예를 들어 :

$ ssh localhost 

은 다음과 같이 보일이 연결 문제가 발생할 수 :

$ netstat -nA inet | fgrep :22 
Active Internet connections (w/o servers) 
Proto Recv-Q Send-Q Local Address  Foreign Address  State  
tcp  0  0 127.0.0.1:56039  127.0.0.1:22   ESTABLISHED 
tcp  0  0 127.0.0.1:22   127.0.0.1:56039  ESTABLISHED 

당신이 볼 수 있듯이, 로컬 주소 외국 주소는 동일하지만, 포트 번호는 반전된다. 이 TCP 연결의 고유 한 튜플은 (127.0.0.1, 56039, 127.0.0.1, 22)입니다. 동일한 4 개의 필드가있는 다른 TCP 연결은 없습니다.

두 가지 사실은 컴퓨터가 연결의 양쪽 끝이기 때문입니다. 각각의 끝은 하나는 '외국'이고 다른 하나는 '지역'이라는 자체 견해를 가지고 있습니다.

동일한 포트에서 자신과 연결할 수도 있으며, 일반적인 경우는 아니지만 사양에 의해 금지되지는 않습니다. 다음은이 작업을 수행 할 것입니다 파이썬에서 샘플 프로그램은 다음과 같습니다

import socket 
import time 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.bind(('127.0.0.1', 56443)) 
s.connect(('127.0.0.1', 56443)) 
time.sleep(30) 

는 TCP 연결을 열 가능성이있는 한 가지 방법은 연결의 다른 측면이 동시에 당신과 함께 일을 열려고하는 것입니다 때문에이 코드는 작동 . 이것은 simultaneous SYN exchange으로 알려져 있으며 StackOverflow 응답에 연결된 것은 그게 무엇인지에 대해 설명합니다.

나는 또한 using simultaneous SYN exchange to get through NAT에 대한 논문을 가지고 있지만,이 경우 출처와 외국은 완전히 다릅니다.

+0

으로 연결되었음을 보여줍니다. 그러나 클라이언트가 결국 동일한 포트의 서버를 여는 방법 (게시물의 링크 참조)은 무엇입니까? 결과 서버는 이미 사용중인 서버 포트를 열 수 없습니다. – dimba

+0

AFAIK, 의도적으로 동일한 포트에서 동일한 포트로 연결하지 마십시오 – dimba

+0

@dimba - 이제 코드를 생성하는 방법을 보여주는 코드가 있습니다. 왜 누군가가 그러한 일을하는 것이 다른 질문입니다. 그러나 확실히 가능합니다. – Omnifarious

관련 문제