1.何为WinPcap
百度百科这样解释:WinPcap(windows packet capture)是windows平台下一个免费,公共的网络访问系统。开发winpcap这个项目的目的在于为win32应用程序提供访问网络底层的能力。
总之,WinPcap有很多功能,其中发包使用到的一项就是通过某一网卡给网络中发送原始数据包。需要指出的是,WinPcap发包涉及到MAC层协议,也就是说发包过程处于链路层。所以按照常理,在链路层发包应该会比使用socket的sendTo来发包要快很多,但我通过测试,以及浏览论坛网友的测试结果,都得到二者发包速度差异并不明显的结论。又查了些牛网友的评论,造成这种现象的原因是WinPcap是一种比较粗糙的架构,如果想要提高发包速率需要自己编写驱动协议。
大概了解了Winpcap以及发包的大体情况,开始着手coding了。
2.使用WinPcap开发的准备工作
编写发包程序之前,需要给系统安装winpcap.exe,以及下载其开发包并配置VS。否则,你的code无法运行。
1th,安装WinPcap.exe。下载地址http://www.winpcap.org/install/default.htm,下载完后进行安装。
2th,下载 WinPcap Developer's Pack。下载地址http://www.winpcap.org/devel.htm,注意需要和winpcap.exe的版本一致。
3th,配置microsoft visual studio。我使用的是VS2008,VS版本不一样配置细节不一样,但大体方法一致。
首先,找到Tools->Options->Projects and Solutions->VC++ Directories, show directories for 选择include files,增加开发包里的include文件夹。
同理,配置library files, 添加开发包中的lib文件夹。
其次,建立你自己的发包项目,当前命名为sendPackets,之后找到Project->sendPackets Properties->configureation properties->c/c++->preprocessor, 在右边的preprocessor definitions 一项中添加WIN32;
_DEBUG;_CONSOLE;WPCAP;HAVE_REMOTE。
继续在左边栏选择Linker, 在右边栏additional library directories中添加开发包中lib文件夹路径。
这样,准备工作就做好了。进行开发时应该不会有问题了,如果你没有完全按照我说的去做会出现以下问题。
问题1:
can't find wpcap.dll找不到动态链接库的毛病,请先下载安装winpcap
问题2:
Cannot open include file: 'pcap.h': No such file or directory找不到文件的错误,请察看是否加入了winpcap开发包的include文件夹。
问题3:
fatal error LNK1104: cannot open file "wpcap.lib"问题,请察看是否加入了winpcap开发包的lib文件夹.
问题4:
error LNK2001: unresolved external symbol _pcap_findalldevs问题,请察看link中是否加入了wpcap.lib.以及是否对c/c++预处理器进行定义。
怎么解决?看看前面的步骤你漏了哪一步。
3.编写发包程序参考思路
参考开发包中docs目录下的WinPcap_docs.html文件足以能够成功编写发包程序。需要参考guide中的两个内容:Obtaining the device list以及Sending Packets。
思路:参考第一个材料获取网卡列表,参考第二个材料选择刚才获取的一个网卡名编写发包程序。
第二个材料中,你完全不需要使用main函数的参数argc以及argv,pcap_open(...)中的第一个参数网卡名使用你获取的任意一个网卡即可。
我的对于包大小和测试发包率的相关代码如下(不能直接运行,部分代码,自己动手写吧,只是参考):
#define PACKET_SIZE 1460
#define SEND_TIMES 65536 //发包总次数
if (pcap_sendpacket(fp, packet, PACKET_SIZE) != 0){
fprintf(stderr,"\nError sending the packet: %s\n", pcap_geterr(fp));
return;
}
long t=GetTickCount();
for(int i=0;i<SEND_TIMES;i++){
pcap_sendpacket(fp, packet, PACKET_SIZE);
}
int packetSize=PACKET_SIZE;
printf("Packet size is %d Bytes .\n",packetSize);
t=GetTickCount()-t;
double sendRate=SEND_TIMES*1000*1.0/t; //发送速率
printf("The sending rate is %f/s . \n",sendRate);
看下效果。没有达到1GE的标准,还差一个数量级。。。