두 응용 프로그램이 같은 포트를 수신 할 수 있습니까?


283

동일한 컴퓨터의 두 응용 프로그램이 동일한 포트 및 IP 주소에 바인딩 될 수 있습니까? 한 걸음 더 나아가서 하나의 앱이 특정 IP의 요청과 다른 원격 IP의 요청을들을 수 있습니까? 두 개의 스레드 (또는 포크)로 시작하여 비슷한 동작을하는 하나의 응용 프로그램을 가질 수 있지만 공통점이없는 두 응용 프로그램은 동일하게 작동 할 수 있습니까?


2
: 여러 소켓 주소 / 포트를 재사용에 좋은 상세한 답변 stackoverflow.com/questions/14388706/...을
Bjarke 프로 인트 - 한센을

답변:


248

대답은 고려중인 OS에 따라 다릅니다. 그러나 일반적으로 :

TCP의 경우 아니요. 한 번에 하나의 응용 프로그램 만 동일한 포트에서 청취 할 수 있습니다. 이제 2 개의 네트워크 카드가있는 경우 동일한 포트 번호를 사용하여 하나의 응용 프로그램이 첫 번째 IP에서 수신하고 두 번째 IP에서 두 번째 IP를 수신하도록 할 수 있습니다.

UDP (멀티 캐스트)의 경우 여러 응용 프로그램이 동일한 포트를 구독 할 수 있습니다.

편집 : Linux Kernel 3.9 이상부터 동일한 포트를 수신하는 여러 응용 프로그램에 대한 지원이 SO_REUSEPORT옵션을 사용하여 추가되었습니다 . 자세한 내용은 이 lwn.net 기사를 참조하십시오.


22
"단일 포트에서 수신 대기하는 하나의 응용 프로그램"은 포트가 존재하는 이유이므로 여러 응용 프로그램이 충돌없이 네트워크를 공유 할 수 있습니다.
S.Lott

46
IP 주소 당 포트 당 하나의 리스너. 다른 네트워크 인터페이스를 추가하면 두 번째 IP 주소를 얻을 수 있습니다. 귀하의 플랫폼은 하나의 물리적 네트워크 카드로 두 개의 IP 주소를 얻는 또 다른 방법 인 가상 인터페이스를 지원할 것입니다.
John M

7
지금까지는 같은 의견을 가지고 있었지만 두 개의 다른 프로세스를 동일한 ip 및 TCP 포트에 바인딩 할 수있었습니다. 바인딩하기 전에 Java에서 ServerSocket.setReuseAddress (true)를 설정 한 경우 가능합니다. 정말 예상치 못한 행동.
Eugen

7
(1) 대답의 실제 의미는 'TCP의 경우 예, 제공됩니다 ...'입니다. (2) 멀티 캐스트는 UDP 포트 공유의 전제 조건은 아니지만 SO_REUSEADDR입니다.
Lorne의 후작

12
UDP (멀티 캐스트)의 경우 여러 응용 프로그램이 동일한 포트를 구독 할 수 있습니다. 하나의 패킷이 클라이언트에서 도착한 경우 어떤 응용 프로그램에서 수신합니까?
Yang Juven

123

예 (TCP의 경우) 프로그램이 그렇게 설계된 경우 두 개의 프로그램이 동일한 소켓에서 청취하도록 할 수 있습니다. 첫 번째 프로그램에서 소켓을 작성할 때 SO_REUSEADDR옵션을 소켓에 설정해야합니다 bind(). 그러나 이것은 당신이 원하는 것이 아닐 수도 있습니다. 이것이하는 일은 들어오는 TCP 연결이 둘 중 하나 가 아닌 프로그램 중 하나 에 전달되므로 연결을 복제하지 않고 두 프로그램이 들어오는 요청을 처리 할 수있게하는 것입니다. 예를 들어, 웹 서버에는 포트 80에서 수신 대기하는 여러 프로세스가 있으며 O / S는 새 연결을 수락 할 준비가 된 프로세스에 새 연결을 보냅니다.

SO_REUSEADDR

bind()활성 청취 소켓이 이미 포트에 바인드되어 있지 않으면 다른 소켓을 이 포트에 연결할 수 있습니다. 그러면 충돌 후 서버를 다시 시작하려고 할 때 "이미 사용중인 주소"오류 메시지가 표시됩니다.


1
TCP + UDP가 작동합니다 (새로운 커널이 충분히 제공됨). 답변에 추가 한 링크를 참조하십시오.
dpb

3
모든 소켓이 INADDR_ANY가 아닌 다른 IP 주소에 바인드되지 않았거나 Windows에 있지 않은 경우 (결과가 정의되지 않은 경우)이 대답은 올바르지 않습니다.
Lorne의 후작

1
동일한 포트에서 특정 앱으로 데이터가 전달되는 방식을 확장 할 수 있습니까? 앱에서 SO_REUSEADDR 또는 SO_REUSEPORT를 사용할 때 고려해야 할 보안 문제가 있습니까?
trusktr

@EJP 또한 내 이전 의견을 살펴볼 수 있습니까?
trusktr

3
SO_REUSEADDR확실히 유닉스에서 적어도 두 개의 TCP 소켓을 동시에 청취 상태에 두지 못하게하십시오. 해결하기 위해 의미 것 TIME_WAIT state: unixguide.net/network/socketfaq/4.5.shtml를 . Windows에서는 작동하지만 요청이 올바른 서버에 도달한다고 보장하지는 않습니다.)
Bruno

48

예.

  1. 모두 동일한 포트에 바인딩 된 여러 수신 TCP 소켓이 서로 다른 로컬 IP 주소에 바인딩되어 있으면 공존 할 수 있습니다. 클라이언트는 필요한 어느 쪽이든 연결할 수 있습니다. 제외0.0.0.0( INADDR_ANY)는 .

  2. 여러 개의 승인 된 소켓이 공존 할 수 있으며 모두 동일한 청취 소켓에서 승인되며 모두 청취 소켓과 동일한 로컬 포트 ​​번호를 표시합니다.

  3. 동일한 포트에 바인드 된 여러 UDP 소켓은 모두 (1)과 동일한 조건으로 제공되거나 모두 SO_REUSEADDR바인딩 전에 옵션이 설정되어 있습니다.

  4. TCP 포트와 UDP 포트는 서로 다른 네임 스페이스를 차지하므로 TCP에 포트를 사용한다고해서 UDP에 대한 사용을 배제하지 않으며 그 반대도 마찬가지입니다.

참조 : Stevens & Wright, TCP / IP Illustrated, Volume II.


당신은 손에 링크가 있습니까? TCP-UDP 공존의 기회는 바로 제 질문입니다. 미리 감사드립니다 :)
늑대

1
@ 늑대 그냥 시도해보십시오. 그게 당신이 정말로 필요한 모든 증거입니다. 내 인용은 Stevens & Wright입니다. 그보다 훨씬 나아질 수는 없습니다.
Lorne의 후작

1
답변 주셔서 감사합니다, 더 세 심하게 읽어야합니다. 이미 UDP와 TCP 가 공존 할 수 있다고 썼습니다 .
Wolf

47

원칙적으로

그것은 돌로 쓰여지지 않았습니다. 그러나 모든 API가 작성되는 방식입니다. 앱이 포트를 열고 핸들을 가져오고 클라이언트 연결 (또는 UDP 경우 패킷)이 도착하면 OS는 해당 핸들을 통해 포트에 알립니다.

OS에서 두 개의 앱이 같은 포트를 열도록 허용 한 경우 어떤 앱에 알릴 수 있습니까?

그러나 ... 그 주위에는 방법이 있습니다.

  1. Jed가 지적했듯이 클라이언트 요청을 분리하려는 논리를 사용하여 실제로 포트에서 수신하고 다른 사람에게 알리는 유일한 프로세스 인 '마스터'프로세스를 작성할 수 있습니다.
    • Linux 및 BSD에서 (적어도) 네트워크 관련 기준 (원산지 네트워크 또는 간단한 형태의로드 밸런싱).

37
iptables -m statistic --mode random --probability 0.5재미있다.
Jed Smith

1
"포트 열기"는 정확히 무엇을 의미합니까? 문장을 이해하지만 포트를 열고 처리 할 때 시스템이 정확히 무엇을하는지 알고 있습니까? TCP로 포트를 열고 싶을 때 스트림을 얻었고 해당 스트림은 리모트와의 연결이지만 웹에서 검색하고 좋은 설명을 찾지 못했습니다.
사무엘

4
@Samuel : 포트를 여는 것은 (서버 모드에서) 파일 디스크립터를 얻는 것을 의미하며 시스템이 해당 포트 번호로 SYN 패킷을 받으면 SYN + ACK로 응답하여 연관된 파일 디스크립터에서 이벤트를 생성합니다. 애플리케이션은 accept () 호출로 해당 이벤트에 응답하여 특정 스트림과 연관된 새 파일 디스크립터를 작성하여 원래 서버 디스크립터가 클라이언트로부터 새 연결을 확보 할 수 있도록합니다.
Javier

7
이 답변은 올바른 것으로 간주 될 수 없습니다. SO_REUSEADDR과 SO_REUSEPORT의 존재를 완전히 간과합니다.
Lorne의 후작

@Javier 아닙니다. 서버 응용 프로그램의 관점에서 포트를 열면 수신 소켓을 바인딩하거나 곧 소켓을 바인딩 할 때 발생합니다 listen(). 아마도 방화벽에서 방화벽을 여는 것에 대한 질문 일 것입니다. 여기에 너무 많은 오류가 있으며 7 년 안에 모두 수정되지 않았습니다. 또한 포트 번호가 동일한 다른 로컬 주소에 바인딩하는 경우에도 답변이 생략됩니다. 사실 완전히 틀 렸습니다.
Lorne의 후작

27

그렇습니다 . 내가 기억하는 한 커널 버전 3.9 (버전에 대해서는 확실하지 않음)부터에 대한 지원 SO_REUSEPORT이 도입되었습니다.SO_RESUEPORT첫 번째 서버가 소켓을 바인딩하기 전에이 옵션을 설정하는 한 정확히 동일한 포트 및 주소에 바인딩 할 수 있습니다.

TCPUDP 모두에서 작동합니다 . 자세한 내용은 링크를 참조하십시오 : SO_REUSEPORT

노트 : 수락 된 답변은 더 이상 내 의견으로는 사실이 아닙니다.


2
완전 사실입니다. 사실이 아니라면 Wireshark는 어떻게 작동합니까?
Staszek

5
@Staszek Wireshark가 포트를 수신하지 않습니다. 패킷 수준에서 작동합니다.
Lorne의 후작

오, 말이 되겠네요 어쨌든, 2 개의 앱으로 2 개의 포트를 듣는 것이 가능합니다.
Staszek

18

아니오. 한 번에 하나의 응용 프로그램 만 포트에 바인드 할 수 있으며 바인드가 강제 실행되는 경우의 동작은 미정입니다.

SO_REUSEADDR이 각 소켓의 옵션에 설정되어있는 한 멀티 캐스트 소켓 (원하는 곳에서 아무 소리도 들리지 않음)을 사용하면 둘 이상의 응용 프로그램이 포트에 바인딩 될 수 있습니다.

"마스터"프로세스를 작성하여 모든 연결을 수락하고 처리 한 다음 동일한 포트에서 수신 대기해야하는 두 응용 프로그램에 연결하여이 작업을 수행 할 수 있습니다. 많은 프로세스가 80을 수신해야하기 때문에 이것이 웹 서버 및 이와 같은 접근 방식입니다.

이 외에도, 우리는 세부 사항을 얻고 있습니다-TCP와 UDP 모두에 태그를 지정했습니다. 또한 어떤 플랫폼입니까?


둘 다 나에게 관심이있다. 플랫폼은 Windows이지만 Linux에 대한 답변이 다른 경우에는 알 수 있습니다.
nadiv

8
멀티 캐스트 소켓과 같은 것은 없습니다. UDP 소켓이 있습니다. 멀티 캐스트는 SO_REUSEADDR의 전제 조건이 아닙니다.
Lorne의 후작

3

하나의 응용 프로그램이 하나의 포트에서 하나의 네트워크 인터페이스를 수신하도록 할 수 있습니다. 따라서 다음을 수행 할 수 있습니다.

  1. httpd 원격으로 액세스 가능한 인터페이스에서 청취 192.168.1.1:80
  2. 다른 데몬 청취 127.0.0.1:80

샘플 사용 사례 httpd는로드 밸런서 또는 프록시 로 사용할 수 있습니다 .


3

다른 방법은 하나의 포트에서 수신하는 프로그램을 사용하여 트래픽의 종류 (ssh, https 등)를 분석하여 내부적으로 "실제"서비스가 수신하는 다른 포트로 리디렉션하는 것입니다.

예를 들어 Linux의 경우 sslh : https://github.com/yrutschle/sslh


창문에 그런 프로그램이 있습니까? 로컬 IIS 서버와 ActiveMQ 브로커 모두 포트 443에서 수신 대기해야합니다.
Harvey Lin

3

TCP 연결을 만들 때 IP 주소 (사용중인 프로토콜에 따라 v4 또는 v6)와 포트의 조합 인 특정 TCP 주소에 연결하도록 요청합니다.

서버는 연결을 수신 대기 할 때 특정 IP 주소 및 포트 (예 : 하나의 TCP 주소) 또는 각 호스트의 IP 주소 (대개 IP 주소로 지정됨)의 동일한 포트를 수신하고 싶다고 커널에 알릴 수 있습니다. 0.0.0.0), 효과적으로 (다른 "TCP 주소"많은 청취하는 예 192.168.1.10:8000,127.0.0.1:8000 , 등)

아니오, 메시지가 들어올 때 커널이 어떤 응용 프로그램에 메시지를 제공하는지 알기 때문에 동일한 "TCP 주소"에서 수신 대기하는 두 개의 응용 프로그램을 가질 수 없습니다.

그러나 대부분의 운영 체제에서 단일 인터페이스에 여러 개의 IP 주소를 설정할 수 있습니다 (예 : 인터페이스가 192.168.1.10있는 192.168.1.11경우 네트워크의 다른 사람이 사용하지 않는 경우 에도 설정할 수 있음). 이 8000두 IP 주소 각각 에서 포트 를 수신하는 별도의 응용 프로그램을 가질 수 있습니다 .


2

원격 IP 중 하나 이상이 이미 알려져 있고 정적이며 앱 중 하나와 만 통신하도록 전용 인 경우 iptables 규칙 (테이블 nat, 체인 PREROUTING)을 사용하여 들어오는 주소를이 주소에서 "공유"로컬 포트로 리디렉션 할 수 있습니다. 적절한 응용 프로그램이 실제로 수신하는 다른 포트


1

예, 아니오 하나의 응용 프로그램 만 포트에서 능동적으로 수신 할 수 있습니다. 그러나 해당 응용 프로그램은 다른 프로세스와의 연결을 방해 할 수 있습니다. 따라서 동일한 포트에서 여러 프로세스가 작동 할 수 있습니다.


@trusktr, 나는 그가 의미하는 생각
warvariuc

1

예.

이 기사에서 :
https://lwn.net/Articles/542629/

새로운 소켓 옵션을 사용하면 동일한 호스트의 여러 소켓이 동일한 포트에 바인딩 될 수 있습니다


1
멋진 링크는 그러나이 선이 기록되지 않음 - SO_REUSEPORT 옵션이 아닌 표준
사힐 싱

0

응용 프로그램에서 여러 프로세스를 의미하는 경우 예이지만 일반적으로 아니요입니다. 예를 들어 Apache 서버는 동일한 포트에서 여러 프로세스를 실행합니다 (일반적으로 80). 프로세스 중 하나를 지정하여 실제로 포트에 바인딩 한 다음 해당 프로세스를 사용하여 연결을 수락하는 다양한 프로세스로 핸드 오버를 수행합니다.


0

두 개의 응용 프로그램이 동일한 네트워크 인터페이스에서 동일한 포트를 청취하도록 할 수 있습니다.

지정된 네트워크 인터페이스 및 포트에 대해 하나의 청취 소켓 만있을 수 있지만 해당 소켓은 여러 응용 프로그램간에 공유 될 수 있습니다.

애플리케이션 프로세스에 청취 소켓이 있고 fork해당 프로세스가 있으면 소켓이 상속되므로 기술적으로 동일한 포트를 청취하는 두 개의 프로세스가 있습니다.


0

나는 다음을 시도했다 socat.

socat TCP-L:8080,fork,reuseaddr -

소켓에 연결하지 않았지만 동일한 포트에서 두 번 청취 할 수는 없습니다. reuseaddr 옵션 .

이 메시지가 나타납니다 (이전에 예상 했음).

2016/02/23 09:56:49 socat[2667] E bind(5, {AF=2 0.0.0.0:8080}, 16): Address already in use

0

@jnewton이 언급 한 것을 공유하십시오. Mac에서 nginx와 내장 Tomcat 프로세스를 시작했습니다. 8080에서 두 프로세스를 모두 볼 수 있습니다.

LT<XXXX>-MAC:~ b0<XXX>$ sudo netstat -anp tcp | grep LISTEN
tcp46      0      0  *.8080                 *.*                    LISTEN     
tcp4       0      0  *.8080                 *.*                    LISTEN   

-2

짧은 답변:

여기에 주어진 대답으로 갑니다. 동일한 IP 주소와 포트 번호로 수신 대기하는 두 개의 응용 프로그램을 가질 수 있으므로 포트 중 하나는 UDP 포트이고 다른 하나는 TCP 포트입니다.

설명:

포트 개념은 TCP / IP 스택의 전송 계층과 관련이 있으므로 스택의 다른 전송 계층 프로토콜을 사용하는 경우 동일한 프로세스에서 여러 프로세스를 청취 할 수 있습니다 <ip-address>:<port> 조합 .

사람들이 가지고있는 한 가지 의심은 두 응용 프로그램이 동일한 <ip-address>:<port>조합으로 실행되고 있다면 원격 컴퓨터에서 실행되는 클라이언트 가 두 응용 프로그램을 어떻게 구별 할 수 있을까요? IP 계층 패킷 헤더를 보면 ( https://en.wikipedia.org/wiki/IPv4#Header )를 보면 프로토콜을 정의하는 데 72-79 비트가 사용된다는 것을 알 수 있습니다. 이는 구별 방법입니다.

그러나 동일한 TCP에서 두 개의 응용 프로그램을 사용하려는 경우 <ip-address>:<port> 조합으로 대답은 없습니다 (재미있는 연습은 두 개의 VM을 시작하고 동일한 IP 주소를 제공하지만 다른 MAC 주소를 제공하며 어떤 일이 발생하는지 확인합니다. VM1은 패킷을 가져오고 다른 경우 VM2는 ARP 캐시 새로 고침에 따라 패킷을 가져옵니다.

두 응용 프로그램을 동일하게 실행하면 <op-address>:<port> 하면 어떤 종류의로드 균형 조정을 달성 할 수 . 이를 위해 다른 포트에서 응용 프로그램을 실행하고 IP 테이블 규칙을 작성하여 이들 사이의 트래픽을 분기 할 수 있습니다.

@ user6169806의 답변도 참조하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.