xid := os.Getpid()&0xffff
有人知道这里&0xffff起什么作用吗?
我在许大的《go语言编程》第5章看到的icmp的例子
不知道这几句是什么意思,起什么作用的
sum = (sum >> 16) + (sum & 0xffff)
sum += (sum >> 16)
var answer uint16 = uint16(^sum)
原方法
func checkSum(msg []byte) uint16 {
sum := 0
for n := 1; n < len(msg)-1; n += 2 {
sum += int(msg[n])*256 + int(msg[n+1])
}
sum = (sum >> 16) + (sum & 0xffff)
sum += (sum >> 16)
var answer uint16 = uint16(^sum)
return answer
}
汇编方式使代码更有效率,知识大多数是移位和校验,
具体原理看这里 :http://www.360doc.com/content/11/0124/10/1317564_88646216.shtml
PID原本也是16 bit的。所以这段代码也没错误。os.Getpid()&0xffff
只取Pid低16位。
这通常出现在RAW Socket请求的代码中。Packet的header中需要一个唯一ID,通常就用当前进程的PID了。但这个id
是要求unsigned short(16 bit),所以就取os.Getpid()&0xffff
了。
C语言这样做还可以理解,但我不知道为什么golang也要这样做。
知不道。
后面一个checkSum函数是一种常见的 Internet checksum算法。
//就是将一个32位的数的高16位加上低16位
sum = (sum >> 16) + (sum & 0xffff)
//再将结果的高16位加上自身
sum += (sum >> 16)
//因为tcp checksum数据大小也是16位,所以
var answer uint16 = uint16(^sum)
实际上,上面的代码和前面for循环将msg每一个byte相加是差不多一回事。相当于对sum这个int数据再进行一次简单的check sum。
其实常见的写法是:
/* Fold to get the ones-complement result */
while (sum >> 16) sum = (sum & 0xFFFF)+(sum >> 16);
参考:
- http://www.netfor2.com/checksum.html
- http://en.wikipedia.org/wiki/IPv4_header_checksum
至于为什么是这个checksum算法,就无力讨论了