멀티 캐스트 (UDP) 소켓을 바인딩한다는 것은 무엇을 의미합니까?
여러 네트워크 인터페이스가있는 호스트간에 멀티 캐스트 UDP를 사용하고 있습니다. 나는 boost :: asio를 사용하고 있으며 수신자가 만들어야 할 두 가지 작업으로 혼란 스럽습니다. bind, then join-group.
가입하는 모든 멀티 캐스트 그룹에 대해 바인딩 할 때 인터페이스의 로컬 주소를 지정해야하는 이유는 무엇입니까?
자매 질문은 멀티 캐스트 포트에 관한 것입니다. 전송하는 동안 멀티 캐스트 주소 및 포트로 전송하기 때문에 멀티 캐스트 그룹에 가입하는 동안 포트가 아닌 주소 만 지정합니다. 묶다.
참고 : "join-group"은 setsockopt(IP_ADD_MEMBERSHIP)문서화 된대로 다른 그룹에 가입하기 위해 동일한 소켓에서 여러 번 호출 될 수있는을 통한 래퍼입니다 (다른 네트워크를 통해?). 따라서 그룹에 가입 할 때마다 bind 호출을 버리고 포트를 지정하는 것이 합리적입니다.
내가보기에 항상 "0.0.0.0"에 바인딩하고 그룹에 참여할 때 인터페이스 주소를 지정하는 것은 매우 잘 작동합니다. 혼란스러워.
멀티 캐스트 수신시 UDP 소켓을 바인드한다는 것은 데이터를 수신 할 주소와 포트를 지정하는 것을 의미합니다 (TCP 수락 자 바인드의 경우와 같이 로컬 인터페이스가 아님). 이 경우에 지정된 주소에는 필터링 역할이 있습니다. 즉, 소켓에 의해 이후에 결합되는 그룹에 관계없이 소켓은 해당 멀티 캐스트 주소 및 포트로 전송 된 데이터 그램 만 수신합니다. 이것은 INADDR_ANY (0.0.0.0)에 바인딩 할 때 멀티 캐스트 그룹으로 전송 된 데이터 그램을 수신 한 반면, 로컬 인터페이스에 바인딩 할 때 데이터 그램이 해당 인터페이스가있는 네트워크에서 전송 되었음에도 불구하고 아무것도 수신하지 않은 이유를 설명합니다. 대응했습니다.
UNIX® Network Programming Volume 1, Third Edition : WR Stevens의 Sockets Networking API에서 인용. 21.10. 보내기 및 받기
[...] 수신 소켓이 239.255.1.2 포트 8888과 같이 멀티 캐스트 그룹과 포트를 바인딩하기를 원합니다. (와일드 카드 IP 주소와 포트 8888 만 바인딩 할 수 있지만 멀티 캐스트 주소를 바인딩하면 소켓이 수신하지 못합니다. 포트 8888을 위해 도착할 수있는 다른 모든 데이터 그램.) 그런 다음 수신 소켓이 멀티 캐스트 그룹에 참여하기를 원합니다. 송신 소켓은 동일한 멀티 캐스트 주소 및 포트 (예 : 239.255.1.2 포트 8888)로 데이터 그램을 보냅니다.
"bind"작업은 기본적으로 "데이터 송수신에이 로컬 UDP 포트를 사용합니다. 즉, 응용 프로그램 전용으로 해당 UDP 포트를 할당합니다. TCP 소켓도 마찬가지입니다."
"0.0.0.0"( INADDR_ANY)에 바인딩하면 기본적으로 TCP / IP 계층에 수신 가능한 모든 어댑터를 사용하고 전송에 가장 적합한 어댑터를 선택하도록 지시하는 것입니다. 이것은 대부분의 소켓 코드에 대한 표준 관행입니다. IP 주소로 0을 지정하지 않는 유일한 경우는 특정 네트워크 어댑터에서 송수신하려는 경우입니다.
마찬가지로 바인딩 중에 포트 값을 0으로 지정하면 OS는 해당 소켓에 대해 임의로 사용 가능한 포트 번호를 할당합니다. 따라서 UDP 멀티 캐스트의 경우 멀티 캐스트 트래픽이 전송 될 것으로 예상되는 특정 포트 번호에서 INADDR_ANY에 바인딩합니다.
"join multicast group"작업 ( IP_ADD_MEMBERSHIP)은 기본적으로 네트워크 어댑터에 대상 MAC 주소가 고유 한 이더넷 프레임을 수신하도록 지시 할뿐만 아니라 이더넷 어댑터 ( NIC )가 다음과 같이 IP 멀티 캐스트 트래픽을 수신하도록 지시하기 때문에 필요합니다. 해당 멀티 캐스트 이더넷 주소에 적합합니다. 각 멀티 캐스트 IP는 멀티 캐스트 이더넷 주소에 매핑됩니다. 소켓을 사용하여 특정 멀티 캐스트 IP로 전송할 때 이더넷 프레임의 대상 MAC 주소는 멀티 캐스트 IP에 해당하는 멀티 캐스트 MAC 주소로 설정됩니다. 멀티 캐스트 그룹에 가입하면 동일한 MAC 주소 (자신의 주소 외에)로 전송 된 트래픽을 수신하도록 NIC를 구성하는 것입니다.
하드웨어 지원이 없다면 멀티 캐스트는 일반 브로드 캐스트 IP 메시지보다 더 효율적이지 않습니다. 조인 작업은 또한 라우터 / 게이트웨이에 다른 네트워크의 멀티 캐스트 트래픽을 전달하도록 지시합니다. (누구 MBONE 기억하세요?)
멀티 캐스트 그룹에 가입하면 해당 IP 주소의 모든 포트에 대한 모든 멀티 캐스트 트래픽이 NIC에 의해 수신됩니다. 바인딩 된 수신 포트로 향하는 트래픽 만 TCP / IP 스택을 통해 앱으로 전달됩니다. 멀티 캐스트 구독 중에 포트가 지정되는 이유는 멀티 캐스트 IP가 바로 IP 전용이기 때문입니다. "포트"는 상위 프로토콜 (UDP 및 TCP)의 속성입니다.
멀티 캐스트 IP 주소가 다양한 사이트에서 멀티 캐스트 이더넷 주소에 매핑되는 방법에 대해 자세히 알아볼 수 있습니다. Wikipedia 기사 는 다음과 같이 좋습니다.
IANA는 OUI MAC 주소 01 : 00 : 5e를 소유하므로 이더넷 MAC 주소 범위 01 : 00 : 5e : 00 : 00 : 00-01 : 00 : 5e : 7f : ff : ff를 사용하여 멀티 캐스트 패킷이 전달됩니다. 23 비트의 사용 가능한 주소 공간입니다. 첫 번째 옥텟 (01)은 브로드 캐스트 / 멀티 캐스트 비트를 포함합니다. 28 비트 멀티 캐스트 IP 주소의 하위 23 비트는 사용 가능한 이더넷 주소 공간의 23 비트에 매핑됩니다.
에 대한 보정 무엇 그것은 멀티 캐스트 (UDP) 소켓을 결합을 의미 하는가? 다음 인용문에서 부분적으로 사실이라면 :
"bind"작업은 기본적으로 "데이터 송수신에이 로컬 UDP 포트를 사용합니다. 즉, 해당 UDP 포트를 응용 프로그램 전용으로 할당합니다.
한 가지 예외가 있습니다. 옵션이 적용된 경우 여러 응용 프로그램 이 수신을 위해 동일한 포트를 공유 할 수 있습니다 (일반적으로 멀티 캐스트 데이터 그램에 실질적인 가치가 있음) SO_REUSEADDR. 예를 들면
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // create UDP socket somehow
...
int set_option_on = 1;
// it is important to do "reuse address" before bind, not after
int res = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &set_option_on,
sizeof(set_option_on));
res = bind(sock, src_addr, len);
여러 프로세스가 이러한 "바인딩 재사용"을 수행 한 경우 해당 공유 포트에서 수신 된 모든 UDP 데이터 그램이 각 프로세스로 전달됩니다 (멀티 캐스트 트래픽과 자연스러운 연결 제공).
다음은 몇 가지 경우에 발생하는 사항에 대한 자세한 내용입니다.
포트 해제에 대한 바인드 ( "독점"또는 "재사용") 시도는 성공합니다.
포트가 이미 "재사용 바인딩"된 경우 "배타적 바인딩"시도가 실패합니다.
일부 프로세스가 "배타적 바인딩"을 유지하면 "바인딩 재사용"시도가 실패합니다.
SENDING 멀티 캐스트 소켓과 RECEIVING 멀티 캐스트 소켓을 구별하는 것도 매우 중요합니다.
멀티 캐스트 소켓 수신에 관한 위의 모든 답변에 동의합니다. OP는 RECEIVING 소켓을 인터페이스에 바인딩해도 도움이되지 않는다고 언급했습니다. 그러나 멀티 캐스트 SENDING 소켓을 인터페이스에 바인딩해야합니다.
멀티 홈 서버의 SENDING 멀티 캐스트 소켓의 경우 보낼 각 인터페이스에 대해 별도의 소켓을 만드는 것이 매우 중요합니다. 각 인터페이스에 대해 바인딩 된 SENDING 소켓을 만들어야합니다.
// This is a fix for that bug that causes Servers to pop offline/online.
// Servers will intermittently pop offline/online for 10 seconds or so.
// The bug only happens if the machine had a DHCP gateway, and the gateway is no longer accessible.
// After several minutes, the route to the DHCP gateway may timeout, at which
// point the pingponging stops.
// You need 3 machines, Client machine, server A, and server B
// Client has both ethernets connected, and both ethernets receiving CITP pings (machine A pinging to en0, machine B pinging to en1)
// Now turn off the ping from machine B (en1), but leave the network connected.
// You will notice that the machine transmitting on the interface with
// the DHCP gateway will fail sendto() with errno 'No route to host'
if ( theErr == 0 )
{
// inspired by 'ping -b' option in man page:
// -b boundif
// Bind the socket to interface boundif for sending.
struct sockaddr_in bindInterfaceAddr;
bzero(&bindInterfaceAddr, sizeof(bindInterfaceAddr));
bindInterfaceAddr.sin_len = sizeof(bindInterfaceAddr);
bindInterfaceAddr.sin_family = AF_INET;
bindInterfaceAddr.sin_addr.s_addr = htonl(interfaceipaddr);
bindInterfaceAddr.sin_port = 0; // Allow the kernel to choose a random port number by passing in 0 for the port.
theErr = bind(mSendSocketID, (struct sockaddr *)&bindInterfaceAddr, sizeof(bindInterfaceAddr));
struct sockaddr_in serverAddress;
int namelen = sizeof(serverAddress);
if (getsockname(mSendSocketID, (struct sockaddr *)&serverAddress, (socklen_t *)&namelen) < 0) {
DLogErr(@"ERROR Publishing service... getsockname err");
}
else
{
DLog( @"socket %d bind, %@ port %d", mSendSocketID, [NSString stringFromIPAddress:htonl(serverAddress.sin_addr.s_addr)], htons(serverAddress.sin_port) );
}
이 수정 사항이 없으면 멀티 캐스트 전송은 간헐적으로 sendto () errno 'No route to host'를 얻습니다. DHCP 게이트웨이의 플러그를 뽑으면 Mac OS X 멀티 캐스트 SENDING 소켓이 혼란스러워지는 이유를 누구든지 밝힐 수 있다면 듣고 싶습니다.
참고URL : https://stackoverflow.com/questions/10692956/what-does-it-mean-to-bind-a-multicast-udp-socket
'IT Share you' 카테고리의 다른 글
| 현재 날짜를 열의 기본값으로 사용 (0) | 2020.11.17 |
|---|---|
| 자바의 메모리 스트림 (0) | 2020.11.17 |
| grep 결과를 텍스트 파일로 출력하고 더 깨끗한 출력이 필요합니다. (0) | 2020.11.17 |
| 백본 js .listenTo 대 .on (0) | 2020.11.17 |
| 'ReactOwner 만 refs를 가질 수 있습니다.' (0) | 2020.11.17 |