gpt4 book ai didi

c++ - recvfrom 与 INADDR_ANY 一起工作,但指定特定接口(interface)不起作用

转载 作者:行者123 更新时间:2023-11-28 06:33:39 28 4
gpt4 key购买 nike

我写了一个加入源特定多播组并接收 udp 多播数据包的程序:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <net/if.h>

typedef unsigned int UINT32;

int join_ssm_group(int s, UINT32 group, UINT32 source, UINT32 inter) {
struct ip_mreq_source imr;
imr.imr_multiaddr.s_addr = group;
imr.imr_sourceaddr.s_addr = source;
imr.imr_interface.s_addr = inter;
return setsockopt(s, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, (char *) &imr, sizeof(imr));
}

UINT32 LISTEN_INTERFACE = inet_addr("10.10.1.2");

int main(int argc, char *argv[]) {

if (argc<3) {
printf(" Use: %s <group> <source> <port>", argv[0]);
return 1;
}

// Make socket
int sd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);

struct sockaddr_in Sender;
socklen_t SenderAddrSize = sizeof( Sender );

struct sockaddr_in binda;

// Bind it to listen appropriate UDP port
binda.sin_family = AF_INET;
binda.sin_port = htons( atoi(argv[3]));
= INADDR_ANY;
// binda.sin_addr.s_addr = LISTEN_INTERFACE;
bind(sd,(struct sockaddr*)&binda, sizeof(binda));

// Join to group
join_ssm_group( sd, inet_addr(argv[1]),
inet_addr(argv[2]),
INADDR_ANY );

char buf[65536];
UINT32 seq;

while(1) {
printf("try receive\n");
int res=recvfrom(sd,(char*)buf,sizeof(buf),0, (struct sockaddr *)& Sender, &SenderAddrSize);
printf("received\n");
seq = *(UINT32*)buf;
printf("scr=:%12s;\tseq=%6d;\tlen=%4d\n", inet_ntoa(Sender.sin_addr), seq, res);
}

return 0;
}

它工作正常,但请注意我使用的是 binda.sin_addr.s_addr = INADDR_ANY;。 netstat 显示:

netstat -a | grep 16002
udp 0 0 0.0.0.0:16002 0.0.0.0:*

当我将其更改为 binda.sin_addr.s_addr = LISTEN_INTERFACE; 时,程序停止工作 - 它无法接收数据包,它卡在 recvfrom 中。 netstat 显示:

netstat -a | grep 16002
udp 0 0 localhost.localdo:16002 0.0.0.0:*

在这两种情况下,tcpdump 都显示数据在线,所以问题是我无法在特定接口(interface)上接收数据,只能在所有接口(interface)上接收数据。我用的是RHEL 7,teaming,LISTEN_INTERFACE是对应VLAN的IP。为什么我的代码不起作用以及如何排除故障?出于性能原因,我不想使用 INADDR_ANY - 监听所有接口(interface)比监听特定接口(interface)更昂贵。

upd 将 LISTEN_INTERFACE 传递给 join_ssm_groupbinda.sin_addr.s_addr 也不起作用。顺便说一句,此类代码的类似 Windows 版本可在 Windows Server 2008 R2 下的同一台 PC 上运行,但在 RHEL 7 中不起作用。我想我应该检查这些:

  • 如果 RHEL 7 在所需端口的 requreid 接口(interface)上接收数据(答案是肯定的,由 tcpdump 证明)
  • 如果套接字正在所需端口上的所需接口(interface)上监听(答案是肯定的,由 netstat 证明?)
  • 如果以上两个答案都是肯定的,那么调用 recvfrom 怎么可能收不到数据?

这个问题现在可能更多地是关于 RHEL 7,而不是关于 C++。

最佳答案

当您加入多播组时,您需要指定您正在监听的相同接口(interface),或者通过循环中的所有接口(interface)加入它。

然而,监听所有接口(interface)是常态。它并不“慢”,而是一个“好主意”,除非您有特定理由限制谁可以连接。

关于c++ - recvfrom 与 INADDR_ANY 一起工作,但指定特定接口(interface)不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27134949/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com