networking - Centos 不像 Ubuntu 那样接收数据包 - 使用套接字

标签 networking centos sockets

我的服务器上有 CentOS,服务器有两个 NIC。
我想捕获 1 号 NIC 上的任何数据包并将它们转发到 2 号 NIC。我在 C++ 应用程序中使用 Socket 来捕获和转发数据包,然后使用 IPerf 分析我的应用程序。所以我将每个 NIC 连接到不同的计算机(计算机 A 和 B)并尝试将 UDP 数据包从计算机 A 发送到 B。服务器假设从 A 捕获数据包,然后将它们转发到 B,反之亦然。
当我从 A ping 计算机 B 时它运行良好,但是当我尝试通过 IPerf 生成更多数据包时出现了一些问题。 IPerf 每秒生成 100K UDP 数据包(22 字节有效负载)并将其从 A 发送到 B,但计算机 B 不会同时接收所有数据包!例如,如果 A 上的 IPerf 在第一秒发送 100K 个数据包,计算机 B 在 20 秒收到这些数据包!似乎服务器上的某个缓存系统保存了接收到的数据包!让我告诉你发生了什么:

[OS: CentOS]  
[00:00] Computer A Start Sending...  
[00:01] Computer A send 100,000 packets  
[00:01] Finnish  
[00:00] Computer B start to listen...  
[00:01] Computer B receive 300 packets  
[00:02] Computer B receive 250 packets  
[00:03] Computer B receive 200 packets  
[00:04] Computer B receive 190 packets  
[00:05] Computer B receive 180 packets  
[00:06] Computer B receive 170 packets  
[00:07] Computer B receive 180 packets  
[00:08] Computer B receive 20 packets  
[00:09] Computer B receive 3 packets  
[00:10] (same things happened until all 100K packets will receive, it takes long time)  

在第 4 秒,我从计算机 A 上拔下网线以确保它不再发送任何数据包,之后计算机 B 仍在接收数据包!似乎有东西在服务器上保持流量并缓慢释放它。我试图关闭防火墙,但没有任何改变。
我更改了服务器操作系统并使用 Ubuntu 检查我的代码是否有任何问题,但它在 Ubuntu 上运行良好。之后我尝试更改 CentOS 套接字缓冲区大小,但没有帮助。这是我的代码的一些重要部分:
我如何设置套接字:
int packet_socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

if (packet_socket == -1) {
    printf("Can't create AF_PACKET socket\n");
    return -1;
}

// We would use V3 because it could read/pool in per block basis instead per packet
int version = TPACKET_V3;
int setsockopt_packet_version = setsockopt(packet_socket, SOL_PACKET, PACKET_VERSION, &version, sizeof(version));

if (setsockopt_packet_version < 0) {
    printf("Can't set packet v3 version\n");
    return -1;
}


//Set Interface in Promiscuous Mode
struct ifreq ifopts;
strncpy(ifopts.ifr_name,interface_name,IFNAMSIZ-1);
ioctl(packet_socket,SIOCGIFFLAGS,&ifopts);
ifopts.ifr_flags|=IFF_PROMISC;
ioctl(packet_socket,SIOCGIFFLAGS,&ifopts);

//Bind Socket On Specific Interface
struct sockaddr_ll sockll;
bzero((char *)&sockll,sizeof(sockll));
sockll.sll_family=AF_PACKET;
sockll.sll_protocol=htons(ETH_P_ALL);
sockll.sll_ifindex=get_interface_index(interface_name,packet_socket);

bind(packet_socket,(struct sockaddr *) &sockll , sizeof(sockll));

在这里我收到数据包:
u_char *packet;
packet=new u_char[1600];

*length = recv(packet_socket ,packet,1600,0);

在这里我发送数据包:
int res = write(packet_socket ,packet,PacketSize);  

我很困惑,我不知道 CentOS 上发生了什么。你能帮我理解发生了什么吗?
CentOS 是做这项工作的好选择吗?
谢谢你。

最佳答案

尝试在centos上禁用selinux

setenforce 0

然后尝试

关于networking - Centos 不像 Ubuntu 那样接收数据包 - 使用套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47247070/

相关文章:

android - 第一次 HTTP POST 和 GET 尝试总是很慢——这是操作系统相关的还是网络相关的?

windows - 从与主机位于同一网络的外部机器访问 PCF DEV

java - 如何在端口范围内找到开放端口?

ruby-on-rails - ROR 在 CentOS 上的安装

git - git 的包依赖问题在 CEntOS 上需要 : libcurl. so.3

centos - 如何在 centos 中更改/升级我的 GLIBCXX

知道套接字目标进程的 Linux 内核钩子(Hook)

Python3 Windows 多处理传递套接字到进程

azure - 无法为连接到现有本地 Vnet 的新 AKS 群集创建 ACI

.net - [...] Async和Begin [...]。net异步API之间的区别