2016-06-08 6 views
4

내가 실행하는 경우 :tcpdump는 내 C++ 응용 프로그램에 대해 아무것도 표시하지 않습니까?

iperf -s -u -B 224.0.31.155 

sudo tcpdump -ni any 'host 224.0.31.155' 

tcpdump를 실행 뭔가 캡처 할 수있다 : 나는 위의 내 iperf 프로세스를 죽이면, 그러나

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode 
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes 
15:49:15.334484 IP [some ip].14386 > 224.0.31.155.14386: UDP, length 1364 
15:49:15.334728 IP [some ip].14386 > 224.0.31.155.14386: UDP, length 1374 
15:49:15.375026 IP [some ip].14386 > 224.0.31.155.14386: UDP, length 1058 
15:49:15.375184 IP [some ip].14386 > 224.0.31.155.14386: UDP, length 832 

한 다음 시작 내 동일한 그룹에 참여하고 동일한 포트를 바인드하는 C++ 응용 프로그램에서는 tcpdump가 더 이상 트래픽을 볼 수 없습니다.

struct sockaddr_in mc_addr; /* socket address structure */ 
struct ip_mreq mc_req; /* multicast request structure */ 
unsigned int from_len = sizeof(mc_addr); /* source addr length */ 

/* construct a multicast address structure */ 
memset(&mc_addr, 0, from_len); 
mc_addr.sin_family = AF_INET; 
inet_aton(mcastGroup.c_str(), &mc_addr.sin_addr); 
mc_addr.sin_port = htons(port); 

/* bind to multicast address to socket */ 
if (bind(s, (struct sockaddr *) &mc_addr, sizeof(mc_addr)) < 0) { 
    std::cerr << "failed to bind to the port " << port << "|error=" 
      << strerror(errno) << std::endl; 
    throw; 
} 
/* construct an IGMP join request structure */ 
mc_req.imr_multiaddr.s_addr = inet_addr(mcastGroup.c_str()); 
mc_req.imr_interface.s_addr = htonl(INADDR_ANY); 

/* send an ADD MEMBERSHIP message via setsockopt */ 
if ((setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*) &mc_req, 
     sizeof(mc_req))) < 0) { 
    std::cerr << "failed to set socket option to request for membership" 
      << std::endl; 
    throw; 
} 

tcpdump와 세부 사항 : 여기

은 조각이다

$ tcpdump --version 
tcpdump version 4.1-PRE-CVS_2012_03_26 
libpcap version 1.4.0 

난 그냥 내 프로덕션 서버 중 하나를 선택하고 같은 동작을 보여줍니다하지만 난 내 C++ 응용 프로그램임을 알 데이터를 올바르게 처리합니다.

어떤 일이 벌어지고 있는지 알 수 있습니까?

+0

'IP_ADD_MEMBERSHIP'이 무슨 일을할지 모르겠지만'listen '해야 할 수도 있습니다. – Ajay

+0

epoll을 사용하여 파일 설명자를 모니터링하므로 listen()가 필요하지 않습니다. – Hei

+0

"iperf -s -u -B 224.0.31.155"를 실행하여 데이터를 캡처 할 수 있습니까? 듣고있는 서버를 시작한 것 같습니다. 여러분의 코드는 멀티 캐스트 트래픽을 생성하는 것입니다. iperf 명령과 다른 기능을 가진 것 같습니다. 더 자세한 정보를 제공 할 수 있습니까? –

답변

0

코드에서 잠재적 인 문제는 소켓을 멀티 캐스트 주소에 바인딩한다는 것입니다. 이것은 필수는 아니며 모든 종류의 이상한 행동을 유발할 수 있습니다.

에만 UDP 패킷을 보내려면 소켓을 바인딩 할 필요가 없습니다. OS가 대신 해줍니다.

Linux에서 INADDR_ANY에 바인딩하려는 대부분의 멀티 캐스트 트래픽을 보내고 받으려면. 이것은 거의 관용적이다. UDP 소켓의 bind()은 Linux에서 매우 비 직관적 인 의미를 가지고 있습니다. IP 주소에는 필터링 역할 만 있습니다. 지정된 IP 주소에 바인드하거나 IP 주소와 연관된 인터페이스에 바인드하지 않습니다.

또 다른 이상한 점은 mc_req.imr_interface에 할당되는 것이므로 ip_mreq의 회원이 아니어야합니다. 나는 이것이 mc_req.imr_address을 읽어야한다고 생각하지만, 이것이 컴파일되면 나는 침묵 할 것이다.

+0

mcast 메시지를 받고 싶습니다. – Hei

0

IGMP 메시지가 보존됩니다. 호스트가 이미 그룹의 구성원이면 다른 응용 프로그램이 조인 할 때 새 IGMP 멤버쉽 보고서 메시지를 보내지 않습니다. 멀티 캐스트를 받고 있다면 행복해질 것입니다.

+0

한 번씩 잠시 tcpdump를 사용하여 생산 문제를 진단해야하기 때문에이 질문이 제기되었습니다. 감사합니다. – Hei