用C++

2016-10-07 8 views
0

我想接收多播UDP數據的網絡接口上RHEL 7.2用C++

所以,關於我的設置接收在RHEL 7組播數據: 網卡:英特爾X540 IP:192.168.42.100 發行: RHEL 7.2 組播地址:224.5.6.7端口 :2002 接口名稱:ens4f1

我有2個接口打開,1千兆的主板和一個英特爾卡上的10千兆的。

像許多其他職位,我有數據進來,並在wireshark和tcpdump都可見,但我的recvfrom調用只是掛起。我的代碼是一個描述類似問題here的副本,它似乎在爲OP工作。

注:

1)運行我代碼作爲根

2)我試圖在/ proc/SYS /淨/的IPv4/CONF/ens4f1/rp_filter的rp_filter更改爲0無禁用了SELinux沒有改變任何東西改變

3)

4)Wireshark的和tcpdump的顯示就好了數據。自卸圖所示的代碼

#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <time.h> 
#include <string.h> 
#include <stdio.h> 

#include <iostream> 
#include <string> 

using namespace std; 

#define HELLO_PORT 2002 
#define HELLO_GROUP "224.5.6.7" 
#define MSGBUFSIZE 10000 

int main(int argc, char *argv[]) 
{ 
    string source_iface("192.168.42.100"); 
    string group(HELLO_GROUP); 
    int port(HELLO_PORT); 

    cout << "group: " << group << " port: " << port << " source_iface: " << source_iface << endl; 

    int fd; 
    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 
    { 
     perror("socket"); 
     exit(1); 
    } 

    u_int yes = 1; 
    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) 
    { 
     perror("Reusing ADDR failed"); 
     exit(1); 
    } 

    struct sockaddr_in addr; 
    memset(&addr, 0, sizeof(addr)); 

    addr.sin_family = AF_INET; 

    addr.sin_port = htons(port); 
    addr.sin_addr.s_addr = (group.empty() ? 
          htonl(INADDR_ANY) : 
          inet_addr(group.c_str())); 

    if (bind(fd,(struct sockaddr *)&addr, sizeof(addr)) < 0) 
    { 
     perror("bind"); 
     exit(1); 
    } 

    struct ip_mreq mreq; 
    mreq.imr_multiaddr.s_addr = inet_addr(group.c_str()); 
    mreq.imr_interface.s_addr = (source_iface.empty() ? htonl(INADDR_ANY) : inet_addr(source_iface.c_str())); 

    if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) 
    { 
     perror("setsockopt"); 
     exit(1); 
    } 

    socklen_t addrlen; 
    int nbytes; 
    char msgbuf[MSGBUFSIZE]; 

    while (1) 
    { 
     memset(&msgbuf, 0, MSGBUFSIZE); 

     addrlen = sizeof(addr); 
     if ((nbytes = recvfrom(fd, msgbuf, MSGBUFSIZE, 0, (struct sockaddr *)&addr, &addrlen)) < 0) 
     { 
      perror("recvfrom"); 
      exit(1); 
     } 
     cout.write(msgbuf, nbytes); 
     cout.flush(); 
    } 

    return 0; 
} 

所有幫助

[@localhost ~]$ sudo tcpdump -c 5 -i ens4f1 -v 
tcpdump: listening on ens4f1, link-type EN10MB (Ethernet), capture size 65535 bytes 
15:43:57.368470 IP (tos 0x0, ttl 255, id 6526, offset 0, flags [DF], proto UDP (17), length 7996) 
    192.168.42.44.62111 > 224.5.6.7.globe: UDP, length 7968 
15:43:57.368477 IP (tos 0x0, ttl 255, id 6526, offset 0, flags [DF], proto UDP (17), length 316) 
    192.168.42.44.62111 > 224.5.6.7.globe: UDP, length 288 
15:43:57.368869 IP (tos 0x0, ttl 255, id 6526, offset 0, flags [DF], proto UDP (17), length 7996) 
    192.168.42.44.62111 > 224.5.6.7.globe: UDP, length 7968 
15:43:57.368878 IP (tos 0x0, ttl 255, id 6526, offset 0, flags [DF], proto UDP (17), length 316) 
    192.168.42.44.62111 > 224.5.6.7.globe: UDP, length 288 
15:43:57.369264 IP (tos 0x0, ttl 255, id 6526, offset 0, flags [DF], proto UDP (17), length 7996) 
    192.168.42.44.62111 > 224.5.6.7.globe: UDP, length 7968 
5 packets captured 
46 packets received by filter 
9 packets dropped by kernel 

複製和建議者居多

感謝

亨裏克

+0

'netstat -an'和'netstat -ng'顯示什麼? – dbush

+0

-ng顯示我的接口正確加入了多播組。我無法解釋-an輸出,但找不到任何內容看起來像我的程序的路徑,如果這是預期的。我無法給你打印輸出,因爲我在星期一上班之前無法接觸到電腦。 – Henrik

+0

'netstat -an'的輸出應該告訴你你連接的IP /端口。應該有一個IP 224.5.6.7端口2002 udp條目。 – dbush

回答

0

正是有了firewalld的問題在RHEL 7.創建ar這裏描述的這個https://access.redhat.com/solutions/1587673解決了它的一個接口,但不是兩個。如果我沒有解決這個問題,我會重新發布另一個問題。

編輯: 兩個同時運行的罪魁禍首是設置所有接口的rp_filter值爲2。它設置爲僅1如果「所有」類仍爲1

net.ipv4.conf.all.rp_filter=2 

這可以通過創建一個/etc/sysctl.d/multicast.conf文件或使用「sysctl的完成不會做任何事情-w「電話。