tcpdump 对我的 C++ 应用程序没有显示任何内容?
Posted
技术标签:
【中文标题】tcpdump 对我的 C++ 应用程序没有显示任何内容?【英文标题】:tcpdump shows nothing for my C++ application? 【发布时间】:2016-10-08 05:18:50 【问题描述】:如果我跑:
iperf -s -u -B 224.0.31.155
然后运行
sudo tcpdump -ni any 'host 224.0.31.155'
tcpdump 能够捕获一些东西:
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
但是,如果我杀死上面的 iperf 进程,然后启动我的 C++ 应用程序,该应用程序也加入了同一个组并绑定了同一个端口,tcpdump 将不再看到流量。
这里是sn-p:
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++ 应用程序正在正确处理数据。
知道发生了什么吗?
【问题讨论】:
我不确定IP_ADD_MEMBERSHIP
会做什么,但您可能还需要listen
我使用epoll来监控文件描述符,所以不需要listen()。
你可以通过运行“iperf -s -u -B 224.0.31.155”来捕获数据?看来您只是启动了一个正在侦听的服务器。您的代码是生成多播流量,它似乎与您的 iperf 命令具有不同的功能。你能提供更多细节吗?
"iperf -s -u" 表示支持 UDP 的“服务器模式”。它不捕获数据包。它只是加入了多播组,我的代码也是如此——它加入了多播组而不捕获。
@Hei 你的代码对我有用,因为我在你的 sn-p 之后添加了一段时间的睡眠,并从其他节点 iperf -c 224.0.31.155 -u -T 32 -t 1 -i 1 -p 14386
产生了一些流量,也许你可以添加一些代码来读取数据之后你的 sn-p 看看你会得到什么?
【参考方案1】:
IGMP 消息被保留。如果主机已经是组的成员,当另一个应用程序加入时,它不会发送新的 IGMP 成员报告消息。如果您收到多播,请感到高兴。
【讨论】:
我提出这个问题是因为有时我需要使用 tcpdump 来诊断生产中的问题。谢谢。【参考方案2】:您的代码中的一个潜在问题是您将套接字绑定到多播地址。这不是必需的,可能会导致各种奇怪的行为。
如果您只想发送 UDP 数据包,则根本不需要绑定您的套接字。操作系统会为您完成。
如果您想发送和接收多播流量,您很可能希望在 Linux 上绑定到 INADDR_ANY。这几乎是一个成语。 UDP 套接字上的bind()
在 Linux 上具有非常不直观的语义。 IP 地址只是起过滤作用。它既不绑定到指定的 IP 地址,也不绑定到与该 IP 地址关联的接口。
另一个奇怪的事情是你分配给mc_req.imr_interface
,它不应该是ip_mreq
的成员。我认为这应该读为mc_req.imr_address
,但当然,如果它编译,那么我将保持沉默。
【讨论】:
感谢您的评论。我只是想接收 mcast 消息。是的,它符合要求。以上是关于tcpdump 对我的 C++ 应用程序没有显示任何内容?的主要内容,如果未能解决你的问题,请参考以下文章
在 portaudio 中打开原始数据流(例如 tcpdump)
为啥我的 ImageView 没有做任何事情,至少没有重绘?
试图在Discord.py中写一个新文件,但没有任何事情发生