zoukankan      html  css  js  c++  java
  • TCP/IP校验和计算

    校验和思路

    首先,IP、ICMP、UDP和TCP报文头都有检验和字段,大小都是16bit,算法基本上也是一样的。

    在发送数据时,为了计算数据包的检验和。应该按如下步骤:

    1、把校验和字段设置为0;
    
    2、把需要校验的数据看成以16位为单位的数字组成,依次进行二进制反码求和;
    
    3、把得到的结果存入校验和字段中

    在接收数据时,计算数据包的检验和相对简单,按如下步骤:

    1、把首部看成以16位为单位的数字组成,依次进行二进制反码求和,包括校验和字段;
    
    2、检查计算出的校验和的结果是否为0;
    
    3、如果等于0,说明被整除,校验和正确。否则,校验和就是错误的,协议栈要抛弃这个数据包。

    虽然说上面四种报文的校验和算法一样,但是在作用范围存在不同:

    IP校验和只校验20字节的IP报头;
    
    ICMP校验和覆盖整个报文(ICMP报头+ICMP数据);
    
    UDP和TCP校验和不仅覆盖整个报文,而且还有12个字节的IP伪首部,包括源IP地址(4字节)、目的IP地址(4字节)、协议(2字节)、TCP/UDP包长(2字节)。另外UDP、TCP数据报的长度可以为奇数字节,所以在计算校验和时需要在最后增加填充字节0(填充字节只是为了计算校验和,可以不被传送)。

    以下为两个计算校验和的函数

    def carry_around_add(a, b):
        c = a + b
        return (c & 0xffff) + (c >> 16)
    
    
    def checksum2(msg):
        s = 0
        for i in range(0, len(msg), 2):
            w = (ord(msg[i]) << 8) + ord(msg[i + 1])
            s = carry_around_add(s, w)
        return ~s & 0xffff
    
    def checksum(data):  # calculate checksum
        s = 0
        n = len(data) % 2
        for i in range(0, len(data) - n, 2):
            s += ord(data[i]) + (ord(data[i + 1]) << 8)
        if n:
            s += ord(data[i + 1])
        while (s >> 16):
            s = (s & 0xFFFF) + (s >> 16)
        s = ~s & 0xffff
        return s



  • 相关阅读:
    VysorPro助手
    Play 2D games on Pixel running Android Nougat (N7.1.2) with Daydream View VR headset
    Play 2D games on Nexus 6P running Android N7.1.1 with Daydream View VR headset
    Native SBS for Android
    ADB和Fastboot最新版的谷歌官方下载链接
    How do I install Daydream on my phone?
    Daydream Controller手柄数据的解析
    蓝牙BLE传输性能及延迟分析
    VR(虚拟现实)开发资源汇总
    Android(Java)控制GPIO的方法及耗时分析
  • 原文地址:https://www.cnblogs.com/jiufang/p/14490367.html
Copyright © 2011-2022 走看看