我的服务器上有CentOS,服务器有两个网卡。
我想捕获NIC 1号上的任何数据包,并将它们转发到NIC 2号。我在我的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秒内收到这些数据包! 看起来像服务器上的一些caching系统,持有收到的数据包! 让我告诉你发生了什么:
[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)
在第四秒钟,我从电脑A拔下了网线,确认它没有再发送任何数据包,之后电脑B仍在接收数据包! 似乎有东西在服务器上的stream量,并缓慢释放。 我试图closures防火墙,但没有任何改变。
我更改了服务器操作系统,并使用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是做这份工作的好select吗?
谢谢。
尝试在centos上禁用selinux
setenforce 0
然后尝试