首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在linux中低速发送数据包

在linux中低速发送数据包
EN

Stack Overflow用户
提问于 2013-05-22 17:06:32
回答 1查看 410关注 0票数 1

最近正在进行一个项目,该项目是以高速率(超过500 500Mbitps)转发数据包。我试过两种方法,但它们不起作用。主机是vm,ubuntu-11.10 32位,nic是r8169,1000 is。

  1. 我用的是生袜子,它的大小取决于收到的数据包的大小(不超过1500)。我把sendto函数放在循环中(而(1)),确保它能够尽可能快地发送。但是发送速度远低于r8169所能达到的速度,大约是100-200Mbitps。我可以假设套接字不能做高速率发送吗?但是,为什么像Iperf这样的套接字以及使用套接字可以更好地执行呢?或者我能做些什么让发送更快?
  2. 我在内核中使用了dev_queue_xmit()。我将函数放在一个循环中(而(1))在一个带有schedule()的线程中。但是发送速度不超过300 300Mbitps。我知道打电话给dev_queue_xmit可能不是个好主意,但我还是不明白为什么速度这么低?

拜托,需要帮助..。

或者有人能为我提供一个高速率转发数据包的经典解决方案?我的插座很简单:

代码语言:javascript
复制
int sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IP)/*IPPROTO_RAW*/);
struct ifreq if_idx;
char ifName[IFNAMSIZ];
struct sockaddr_ll socket_address;
char buf[1400];
struct packet_mreq mr;
struct ether_header *eh;
int ret = 0;
struct ifreq if_mac;

strcpy(ifName, "eth1");//used for sending
memset(&if_idx, 0, sizeof(struct ifreq));
strncpy(if_idx.ifr_name, ifName, IFNAMSIZ-1);
if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0)
    perror("SIOCGIFINDEX\n");
memset(&if_mac, 0, sizeof(struct ifreq));
strncpy(if_mac.ifr_name, ifName, IFNAMSIZ-1);
if (ioctl(sockfd, SIOCGIFHWADDR, &if_mac) < 0)
    perror("SIOCGIFHWADDR\n");

socket_address.sll_ifindex = if_idx.ifr_ifindex;
/* Address length*/
socket_address.sll_halen = ETH_ALEN;
/* Destination MAC */
socket_address.sll_family = AF_PACKET;
socket_address.sll_protocol = htons(0xA000);
socket_address.sll_addr[0] = 0x00;
socket_address.sll_addr[1] = 0x24;
socket_address.sll_addr[2] = 0xe8;
socket_address.sll_addr[3] = 0x82;
socket_address.sll_addr[4] = 0xec;
socket_address.sll_addr[5] = 0x82;
printf("%d\n",bind(sockfd, (struct sockaddr *) &socket_address, sizeof(socket_address))); 

memset (&mr, 0, sizeof(mr));
mr.mr_ifindex = if_idx.ifr_ifindex;
//mr.mr_type = PACKET_MR_PROMISC;
setsockopt(sockfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr,sizeof(mr));

eh = (struct ether_header *)buf;
eh->ether_shost[0] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[0];
eh->ether_shost[1] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[1];
eh->ether_shost[2] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[2];
eh->ether_shost[3] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[3];
eh->ether_shost[4] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[4];
eh->ether_shost[5] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[5];
eh->ether_dhost[0] = 0x00;
eh->ether_dhost[1] = 0x24;
eh->ether_dhost[2] = 0xe8;
eh->ether_dhost[3] = 0x82;
eh->ether_dhost[4] = 0xec;
eh->ether_dhost[5] = 0x82;
eh->ether_type = htons(0xA000);
while(1)
    ret = write(sockfd,buf,1000);
printf("%d\n",ret);
return 0;
EN

回答 1

Stack Overflow用户

发布于 2013-05-23 07:54:16

您看过写(),它允许您提供多个缓冲区吗?您是从文件中获取数据吗?如果是这样的话,您可能需要调查sendfile()。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16697687

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档