读书人

大牛,怎么提高WINDOWS 下用socket 发送

发布时间: 2012-03-05 11:54:03 作者: rapoo

请教各位大牛,如何提高WINDOWS 下用socket 发送 UDP包的速度
问题描述:

有两台4核的服务器,装的windows2003 都是千兆网卡, 用千兆交换机相连
在一台机器上用WIN socket api 写了个发送UDP包的小程序, 包中的数据长度为180字节
在另一台机器上装了个抓包器, 来记录受到了多少个包,经过测试,测试数据如下

发送5秒, 收到234605个包
发送10秒,收到438570个包
发送15秒,收到750597个包

网卡的使用率都是10%

可以看到每秒才能发送4万多个包,这对目前项目的需求来说太少了,想问下如何能提高发送速度?
代码如下:


#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#include <iostream>

#include <time.h>


int main()
{

char log[256] = "20100119161638|20100118184827|20100119235141|3|10.90.177.67|53391|117.136.31.195|21920|211.136.192.6|53391|0.0.0.0|0|0|0|17|218|1";
WSADATA wsd;
if(WSAStartup(MAKEWORD(2,2),&wsd)) {
cerr << "WSAStartup error..." << endl;
return INVALID_SOCKET;
}

SOCKET sockClient = socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_family = AF_INET;
addrSrv.sin_addr.S_un.S_addr = inet_addr("172.18.11.32");
addrSrv.sin_port = htons(514);
bind(sockClient,(SOCKADDR*)&sockClient,sizeof(SOCKADDR));

unsigned long sendTime = 20;//发送时间


time_t nowTime = time(NULL);
time_t endTime = nowTime + sendTime ;


while(time(NULL) < endTime)
{
sendto(sockClient,log,strlen(log)+1,0,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
}


std::cout << "finished sending " << std::endl;

closesocket(sockClient);
WSACleanup();

getchar();

}

[解决办法]
首先,应该在发送端计数
UDP是会丢包的,收到多少不等于发送了多少
第二,接收和发送的效率可能都需要提高,你可以试试多开几个发送端,按现有的速度发送,接收到的数据包数量是多少,搞清楚瓶颈是在发送,还是在接收,然后才有针对性的进行修改
[解决办法]
想要提高速度,最好直接操作网卡,即自己写驱动
[解决办法]
可以这样试下,main中开线程发送UDP包,把线程优先级提高到2,即比普通线程高2个等级。CPU调度应该更高一些。
//THREAD_PRIORITY_ABOVE_NORMAL 1
//THREAD_PRIORITY_BELOW_NORMAL -1
//THREAD_PRIORITY_HIGHEST 2
//THREAD_PRIORITY_IDLE -15
//THREAD_PRIORITY_LOWEST -2
//THREAD_PRIORITY_NORMAL 0
//THREAD_PRIORITY_TIME_CRITICAL) 15
SetThreadPriority( m_Thread, THREAD_PRIORITY_HIGHEST);
[解决办法]

探讨
可以这样试下,main中开线程发送UDP包,把线程优先级提高到2,即比普通线程高2个等级。CPU调度应该更高一些。
//THREAD_PRIORITY_ABOVE_NORMAL 1
//THREAD_PRIORITY_BELOW_NORMAL -1
//THREAD_PRIORITY_HIGHEST 2
//THREAD_PRIORITY_IDLE -15
//THR……

[解决办法]
目前看来应该是接收端有问题,瓶颈是在接收端,把发送的包都给丢掉了

探讨

引用:
首先,应该在发送端计数
UDP是会丢包的,收到多少不等于发送了多少
第二,接收和发送的效率可能都需要提高,你可以试试多开几个发送端,按现有的速度发送,接收到的数据包数量是多少,搞清楚瓶颈是在发送,还是在接收,然后才有针对性的进行修改



试了下,在发送端是比在接收端每秒大约多了1万个包

同时开了5个发送端, 接收端收到的包的总数基本……

[解决办法]
一次send的系统调用时间是20us, 1S可以进行50K次的调用。一个MTU是1.4K,即1S可以达到70MB流量,560MBPS的占有率。鉴于现在CPU速度比外设快多了,我这测试上70%-80%很容易的。。

sendto(sockClient,log,strlen(log)+1,0,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

把strlen什么都改成定值

包大小调为1400bytes看看速度
[解决办法]
探讨
引用:


一次send的系统调用时间是20us, 1S可以进行50K次的调用。一个MTU是1.4K,即1S可以达到70MB流量,560MBPS的占有率。鉴于现在CPU速度比外设快多了,我这测试上70%-80%很容易的。。

sendto(sockClient,log,strlen(log)+1,0,(SOCKADDR*)&addrSrv,s……


[解决办法]
依我看有硬件上也有软件上的瓶颈,硬件上是千兆网卡插在普通PCI插槽上还是PCI-E插槽或主板内置的,
软件上跟以下说的差不多了
探讨
发送端采用多线程,接收端用缓冲池……

[解决办法]
我估计这已经是够快的了,你中间几乎没停顿,不知道下面修改会不会让你的快点

C/C++ code
int len = strlen(log)+1; while(time(NULL) < endTime)  {  sendto(sockClient,log,len,0,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));  }
[解决办法]
局域网内丢包是很少的,而且,假定你丢保率很高,你也该在接收端统计,丢掉的包统计下来也没有用的。楼主应该关心的是“有效”发的包,不包含丢掉的
探讨
首先,应该在发送端计数
UDP是会丢包的,收到多少不等于发送了多少
第二,接收和发送的效率可能都需要提高,你可以试试多开几个发送端,按现有的速度发送,接收到的数据包数量是多少,搞清楚瓶颈是在发送,还是在接收,然后才有针对性的进行修改

读书人网 >C++

热点推荐