在给别人写项目的时候,一个组件涉及到了TCP层的数据发送与接收。
因为项目中这个组件有早起版本,所以也算是接手别人的东西。
看了原来的代码半天云里雾里后决定用Wireshark来抓包,直接看包里面传输的数据格式反倒更简便。
最后把组件搞定后用Wireshark测试的时候发现了好多的包都被标记为 Bad Tcp
把包打开仔细查看后发现只有一个问题就是:header checksum == 0x0000
查阅了大量资料后发现原来是网卡的自动计算校验和在作怪。
网卡驱动的高级配置中,一般有两项叫做Rx Checksum Offload和Tx Checksum Offload
以win7为例,可以看下图所示:
其中的 “IPv4硬件校验和”即对应了这两个选项,它的可选项有“Rx & Tx 开启、Rx开启、Tx开启和关闭”四个。
默认的配置往往是 Rx & Tx 开启。它表示网卡会帮应用进行计算ip头的checksum字段,这样一来,操作系统的ip协议栈无须进行额外的checksum运算,它只需封装好ip 数据报后甩给网卡即可。
甩给网卡的原始ip报文的checksum字段值,原则上是无意义的,即随机的,但是根据windows上的表现来看,这个值一直 是固定0x0000。
猜测一下Wireshark的抓包原理,大概是利用Pcap提供的某种机制,把发给网卡的数据给截获了一份,这样一来,如果操作系统协议栈中出来的ip包的checksum尚未被正确设置,Wireshark完全不知道该数据还会被网卡进行修正,于是它就报错了。
至此,如何使得Wireshark不再抱怨ip头校验错误,答案已经显而易见了,直接选择关闭“IPv4硬件校验和”选项即可(选择“Rx开启”应该也是可行的,这样就相当于关闭了Tx的硬件校验和功能。但是我没有试验过)。