gobook icon indicating copy to clipboard operation
gobook copied to clipboard

icmp的那个实例中checkSum貌似有问题

Open suhanyujie opened this issue 6 years ago • 2 comments

  • 书中的源代码checkSum实现如下,(位于文件https://github.com/qiniu/gobook/blob/master/chapter5/icmptest.go
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
}
  • 实际运行时,会导致代码阻塞在n, err := conn.Read(msg[0:]),运行结果和书中描述的预期不一致
  • 我去网上搜了一下其他的实现方法,大部分如下:
func checkSum(data []byte) uint16 {
	var (
		sum    uint32
		length = len(data)
		index  int
	)
	for length > 1 {
		sum += uint32(data[index])<<8 + uint32(data[index+1])
		index += 2
		length -= 2
	}
	if length > 0 {
		sum += uint32(data[index])
	}
	sum += sum >> 16
	return uint16(^sum)
}
  • 将checkSum替换成使用这种方法实现,程序是可以正常运行的,和书中描述的预期一致

suhanyujie avatar Feb 22 '19 10:02 suhanyujie

的确 会一直阻塞 还以为代码敲错。如果额外开一个bash 然后用系统自带的ping 就会收到数据包

k0njac avatar Sep 08 '21 02:09 k0njac

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)
	fmt.Println(answer)
	return answer
}

62207 阻塞

func checkSum(data []byte) uint16 {
	var (
		sum    uint32
		length = len(data)
		index  int
	)
	for length > 1 {
		sum += uint32(data[index])<<8 + uint32(data[index+1])
		index += 2
		length -= 2
	}
	if length > 0 {
		sum += uint32(data[index])
	}
	sum += sum >> 16
	var answer uint16 = uint16(^sum)
	fmt.Println(answer)
	return answer
}

63437 成功

k0njac avatar Sep 08 '21 02:09 k0njac