2013-05-22 3 views
1

최근에 패킷을 고속으로 (500Mbitps 이상) 전달하는 프로젝트에서 작업 중입니다. 두 가지 방법을 시도했지만 작동하지 않습니다. 호스트는 VM, 우분투 -11.10 32 비트, NIC는 r8169, 1000Mb입니다.리눅스에서 패킷을 느리게 전송하는 패킷

  1. 나는 버킷이있는 버킷을 사용하여 수신 된 패킷의 크기에 따라 다릅니다 (1500 개 이하). sendto 함수를 루프에 넣고 (while (1)) 최대한 빨리 보낼 수 있는지 확인하십시오. 하지만 전송 속도는 r8169가 할 수있는 속도보다 훨씬 더 작습니다. 약 100-200Mbps입니다. 소켓이 고속 전송을 할 수 없다고 생각해도 될까요? 하지만 Iperf와 소켓을 사용하는 것이 더 나은 성능을 낼 수있는 이유는 무엇입니까? 또는 더 빨리 보낼 수있는 방법이 있습니까?

  2. 커널에서 dev_queue_xmit()을 사용했습니다. schedule()을 사용하여 kthread에서 루프 (while (1))에 함수를 넣었습니다. 그러나 전송 속도는 300Mbps를 넘지 못했다. 나는 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

다른 쪽 끝에 wireshark를 사용하고 잠시 후 요약을 확인하십시오. – dcnocomment

+1

반대쪽 끝에 wireshark를 사용하지 마십시오. 그것은 전송 속도를 고립 상태로 보여주지는 않습니다. 그 값은 모든 다른 요인 (네트워크 대역폭, NIC 속도 수신 등)에 영향을받습니다. 송신 측에서 측정하십시오. – 2to1mux

답변

0

당신이 여러 버퍼를 제공 할 수 있습니다 writev() 봤어? 파일의 데이터를 소싱하고 있습니까? 그렇다면 sendfile()을 조사 할 수 있습니다.

관련 문제