2016-09-06 40 views
0

我在Windows上的recvfrom函数有问题我无法解决。
请参阅我写的代码的以下部分。 我在Linux和Windows上运行此代码,并在udp比特率值中获得不同的结果。Windows上的C中的recvfrom函数在使用MinGW时跳过UDP数据

在Windows上使用Cygwin编译它时,我得到了与Ubuntu上相同的结果,可以。我将它与参考工具进行了比较。

当使用MinGW在Windows上编译它时,我得到的upd比特率值较小,这是由于while(1)循环在一秒内(计数器变量)的次数较少而引起的,相关性 - 捕获的数据量较少1秒(data_in_1_sec变量)。似乎使用MinGW在Windows上recvfrom funtion是最慢的,并跳过udp数据。
请注意,在使用MinGW时,如果upd比特率大约为0.200 Mbps,则两个操作系统上的结果都相同。 UDP比特率约为20 Mbps的数据可以看到问题。

不幸的是我不得不使用MinGW,因为这个代码作为静态库被加载到Python代码中。使用CygWin DLL我在Python下运行这个函数时遇到访问冲突。

如何处理?

我使用Windows 7专业版64

码我用:

while (1) { 
    #ifdef _WIN32 
     // start timer 
     QueryPerformanceCounter(&t1);   
    #elif __linux 
     clock_gettime(CLOCK_MONOTONIC, &start); 
    #endif 

    udp_packet_len = recvfrom(sock, udp_packet, buff_len, 0, (struct sockaddr *) &addr, &addrlen); 
    #if DEBUG == 1 
     counter++; 
    #endif 

    #ifdef _WIN32 
     // stop timer 
     QueryPerformanceCounter(&t2);   
    #elif __linux 
     clock_gettime(CLOCK_MONOTONIC, &finish); 
    #endif 

    data_in_1_sec += (double)udp_packet_len; 

    #ifdef _WIN32 
     temp = (t2.QuadPart - t1.QuadPart); 
     temp *= 1000000000.0;  
     temp /= frequency.QuadPart; 
     temp /= 1000000000.0; 
     second += temp; 
    #elif __linux 
     temp = (finish.tv_sec - start.tv_sec); 
     temp += (finish.tv_nsec - start.tv_nsec)/1000000000.0; 
     second += temp; 
    #endif 

    if(second >=1.0) { 
     processing.udp_bitrate = (((data_in_1_sec) * 8.0) /second); 

     #if DEBUG == 1 
      fprintf(stderr,"\nudp_bitrate: %f\n",processing.udp_bitrate); 
      fprintf(stderr,"data_in_1_sec: %f\n",data_in_1_sec); 
      fprintf(stderr,"second: %f\n",second); 
      fprintf(stderr,"counters: %d\n",counter); 
      counter = 0; 
     #endif 

     data_in_1_sec = 0; 
     second = 0.0; 
    } 

这段代码的结果,
对于Windows:

udp_bitrate: 19799823.828382 
data_in_1_sec: 2505664.000000 
second: 1.
counters: 1904 

udp_bitrate: 19389475.566430 
data_in_1_sec: 2451708.000000 
second: 1.011562 
counters: 1863 

udp_bitrate: 18693904.033320 
data_in_1_sec: 2367484.000000 
second: 1.013158 
counters: 1799 

udp_bitrate: 18963187.258098 
data_in_1_sec: 2399068.000000 
second: 1.012095 
counters: 1823 

udp_bitrate: 19452989.621014 
data_in_1_sec: 2459604.000000 
second: 1.011507 
counters: 1869 

udp_bitrate: 19795284.196391 
data_in_1_sec: 2509612.000000 
second: 1.014226 
counters: 1907 

输出为Ubuntu相同数据

udp_bitrate: 22016976.870087 
data_in_1_sec: 2788604.000000 
second: 1.013256 
counters: 2119 

udp_bitrate: 22022223.539749 
data_in_1_sec: 2787288.000000 
second: 1.012536 
counters: 2118 

udp_bitrate: 22003055.797884 
data_in_1_sec: 2785972.000000 
second: 1.012940 
counters: 2117 

udp_bitrate: 22041580.024322 
data_in_1_sec: 2788604.000000 
second: 1.012125 
counters: 2119 

udp_bitrate: 22025510.655441 
data_in_1_sec: 2782024.000000 
second: 1.010473 
counters: 2114 

udp_bitrate: 22412560.109513 
data_in_1_sec: 2801764.000000 
second: 1.000069 
counters: 2129 

回答

0

UDP是不可靠的传输。丢弃数据包是一种允许的行为,并且在数据传输速率超过接收方处理数据的速率的情况下可以预期。

Cygwin和MinGW是单独的项目。他们每个都提供自己的内置在Windows内核和API之上的recvfrom()包装器。可以想象,Cygwin的实现效率更高,在测试条件下比MinGW提供的带宽高10%。

也可能是您的仪器干扰了您的测量。至少某些版本的Cygwin不会默认导致_WIN32由预处理器定义,而MinGW会这样做,所以可能是因为您在Cygwin中使用了clock_gettime(),而在MinGW中使用了Windows性能计数器。你会认为Windows性能计数器的开销很小,因此这种差异可以忽略不计,但是你正在对它进行大量调用。您应该考虑通过针对所有迭代的迭代次数和时间仅对所有这些迭代的总计(仅一个定时器开始/停止每个速率测量)运行测试来减少来自两个源的开销。底线:您的测试方法可以改进,但即使结果能够很好地反映被测试的不同实现的行为,但它们并没有揭示任何根本错误。

相关问题