2013-05-22 4 views
1

Недавно работала над проектом, который предназначен для пересылки пакетов с высокой скоростью (более 500 Мбит/с). Я пробовал 2 метода, но они не работают. Хост - vm, ubuntu-11.10 32bit, nic - r8169, 1000Mb.отправка пакета на низкой скорости в linux

  1. Я использовал сырой носок с баффом, размер которого зависит от размера полученных пакетов (не более 1500). Я положил функцию sendto в цикл (while (1)), убедитесь, что он может отправлять как можно быстрее. но скорость отправки намного меньше, чем скорость r8169, это около 100-200 Мбит/с. Могу ли я предположить, что сокет не может выполнять высокоскоростную передачу? но почему такие, как Iperf, а также использует сокет, могут работать лучше? или Я могу что-то сделать, чтобы сделать отправку быстрее?

  2. Я использовал dev_queue_xmit() в ядре. Я поставил функцию в цикл (while (1)) в kthread с расписанием(). но скорость отправки не превышала 300 Мбит/с. Я знаю, что вызов dev_queue_xmit, может быть, не очень хорошая идея, но я до сих пор не понимаю, почему скорость такая низкая?

пожалуйста, нужна помощь ..

или кто-нибудь может дать мне классическое решение для пересылки пакетов в высокой скорости? мой сокет прост:

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; 
+0

Как вы измерили скорость? – ldx

+0

Я использую wirehark в другом конце и проверяю резюме через некоторое время. – dcnocomment

+1

Не используйте провода на другом конце. Это не показывает вашу скорость отправки в изоляции - на это значение влияют всевозможные другие факторы (пропускная способность сети, скорость передачи данных и т. Д.). Измерьте на отправляющей стороне. – 2to1mux

ответ

0

Вы смотрели на writev(), которая позволяет обеспечить несколько буферов? Собираете ли вы данные из файла? Если это так, вы можете изучить sendfile().

Смежные вопросы