我前段时间,因为需要快速接收数据包的原因,就做了一个完成端口的winsocket接收程序和一个带包过滤的winpcap过滤程序。现在发现winpcap的一个严重问题。由于mtu的限制,一个mtu一般只能发送1。4k多一点的数据,而winpcap所有的接收函数每次只拿一个数据包,也就是说,winpcap一般只接收1.4k多一点的数据,winpcap目前我还不知道有什么办法能接收更大的数据包,或者说接收n条mtu的消息。
winsocket由于能够实现对数据包的组装,所以即使mtu有限制,而通过组装多个mtu的信息,仍然可以实现发送比mtu多很多的数据,比如64k一个包,如果是udp就可以使用winsocket加完成端口实现一次接收64k的设计。而同一个任务,winpcap则要接收将近50次。
由于winpcap的数据接收完是ip包,所以同样是接收udp包,winpcap设置好过滤器后,接收完数据以后,要分析端口,获取数据长度,再拿到有效数据,牵扯到要分析端口,分析数据头,所以实际上,winpcap的接收函数无法做到1G带宽充分利用时的数据接收。我发现一个比较尴尬的问题,在数据量大的时候,比如超过300mb/s注意是小比特,同样的udp包,winsocket加完成端口可以轻松接收,而winpcap由于接收函数的处理能力有限,无法及时快速的拿到所有包。再仔细看winpcap的运行原理,我们发现,winpcap其实使用了packet32,然后packet32会把接收到的所有数据,放在自己的一个缓冲区里面,winpcap到这个缓冲区拿数据,由于缓冲区内数据积累的速度大于winpcap拿走的速度,导致缓冲区满,缓冲区一旦满了,会清空,也就是导致丢数据包了。问题总算是来了,如何才能有效的提高winpcap的读取速度,使这个速度达到1G。是加快数据解析,还是增加mtu的长度,还是能通过某种手段,使winpcap从读一条mtu包变成读n条mtu包。winpcapsocketmtu