校验和算法:IP、IGMP、UDP和TCP报文头部都有检验和字段,其算法都是一样的。

IP、IGMP、UDP和TCP校验和的范围:仅报文头部长度。

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

1、把校验和字段设置为0;

2、把需要校验的数据看成以16位为单位的数子组成,依次进行二进制反码求和(需将溢出位加在低位上);

3、把得到的结果存入校验和字段中。

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

1、把首部看成以16位为单位的数字组成,依次进行二进制反码求和,包括校验和字段;

2、检查计算出的校验和的结果是否为0;

3、如果等于0,说明被整除,校验和正确。否则,校验和就是错误的,协议栈要抛弃这个数据包。

算法代码方案一,先取反后求和,实现如下:

  uBit16 checksum(uBit16 * buffer, int size)
  {
    uBit16 temp = 0;
    uBit16 answer = 0;
    unsigned long cksum = 0;

    while (size > 1)
    {
      answer = *buffer;
      temp = ~answer;
      cksum += temp;
      buffer++;
      size = size - sizeof(uBit16);
    }

    if (size)
    {
      answer = *buffer;
      temp = ~answer;
      cksum += temp;
    }

    while(cksum >> 16)
    {
      cksum = (cksum >> 16) + (cksum & 0xffff);
    }

    answer = (uBit16)cksum;

    return answer;
  }

算法代码方案二,先求和后取反,实现如下:

  uBit16 checksum(uBit16 * buffer, int size)
  {
    uBit16 answer = 0;
    unsigned long cksum = 0;

    while (size > 1)
    {
      answer = *buffer;
      cksum += answer;
      buffer++;
      size = size - sizeof(uBit16);
    }

    if (size)
    {
      answer = *buffer;
      cksum += answer;
    }

    while(cksum >> 16)
    {
      cksum = (cksum >> 16) + (cksum & 0xffff);
    }

    answer = (uBit16)(~cksum);

    return answer;
  }

  说明:以上两种方案都可以正确实现校验和字段,先取反后求和与先求和后取反得到的结果是一样的。  

  注意:以上两种实现方案,都需要将溢出位加在低位上,如 while(cksum >> 16) {cksum = (cksum >> 16) + (cksum & 0xffff);}。传递包头大小时,以实际的包头大小来传递就可以了。

  校验和使用反码求和的优点是:不依赖系统是大端小端。即无论你是发送方计算机或者接收方检查校验和时,都不要调用htons或者ntohs,直接通过上面的算法就可以得到正确的结果。这个问题你可以自己举个例子,用反码求和时,交换16位数的字节顺序,得到的结果相同,只是字节顺序相应地也交换了;而如果使用原码或者补码求和,得到的结果可能就不同。

IP/IGMP/UDP校验和算法的更多相关文章

  1. IP数据报首部校验和算法

    当用google搜索IP数据报首部校验和算法的时候,总是看到的是代码,没有看到其过程,于是就有了此文,如有错误请指正.文章省略一点,呵呵   IP/ICMP/IGMP/TCP/UDP等协议的校验和算法 ...

  2. IP数据包的校验和算法

    1.算法思路: IP/ICMP/IGMP/TCP/UDP等协议的校验和算法都是相同的,算法如下: 在发送数据时,为了计算IP数据包的校验和.应该按如下步骤: (1)把IP数据包的校验和字段置为0: ( ...

  3. mac、ip、udp头解析

    一.MAC帧头定义 /*数据帧定义,头14个字节,尾4个字节*/ typedef struct _MAC_FRAME_HEADER {  char m_cDstMacAddress[6];    // ...

  4. 网络协议: TCP/IP 和UDP/IP

    网络协议: TCP/IP 和UDP/IP TCP/IP TCP/IP(Transmission Control Protocol/Internet Protocol)是一种可靠的网络数据传输控制协议. ...

  5. 传输层协议(tcp ip和udp 三次握手 四次握手)

    1 TCP/IP协议介绍 TCP/IP协议:Transmission Control Protocol/Internet Protocol 传输控制协议/因特网互联协议. TCP/IP是一个Proto ...

  6. 负载均衡算法(四)IP Hash负载均衡算法

    /// <summary> /// IP Hash负载均衡算法 /// </summary> public static class IpHash { static Dicti ...

  7. Socket(套接字) IP TCP UDP HTTP

    Socket(套接字) 阮老师的微博 (转)什么是套接字(Socket)? 应用层通过传输层进行数据通信时,TCP和UDP会遇到同时为多个应用程序进程提供并发服务的问题.多个TCP连接或多个应用程序进 ...

  8. 使用Python计算IP、TCP、UDP校验和

    IP数据报的校验: IP数据报只需要对数据头进行校验,步骤如下: 将接收到的数据的checksum字段设置为0 把需要校验的字段的所有位划分为16位(2字节)的字 把所有16位的字相加,如果遇到进位, ...

  9. WireShark开启IP, TCP,UDP校验和的办法

    首先点击编辑->首选项

随机推荐

  1. sublime 打开import require 模块文件的url 或路径的插件

    结果一番周折,终于发现sublime提供的一个插件(open url)可以实现打开import file 路径的文件,比如import demo from “../path” 的文件在新窗口或者新标签 ...

  2. 图解RabbitMQ

    花点时间重新把rabbitMQ的整体流程粗略的梳理了一遍,便于理解.总体来说,消息产生者->queue->消息消费者可以图解如下: 文字解说:消息产生者 producter 和 consu ...

  3. replace实现替换全部

    方法: string.replace(new RegExp(oldString,"gm"),newString)) gm g=global, m=multiLine , 大致上方法 ...

  4. Python的字典类型

    Python的字典类型为dict,用{}来表示,字典存放键值对数据,每个键值对用:号分隔,每个键值对之间用,号分隔,其基本格式如下: d = {key1 : value1, key2 : value2 ...

  5. swing 下拉菜单

    package rom; import java.lang.*; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; i ...

  6. HDFS在web端无法访问文件

    解决办法1: [root@djt002 hadoop]# vi /etc/selinux/config 改为 SELINUX=disabled 解决办法2: 查看你的$HADOOP_HOME/etc/ ...

  7. git push异常

    git push异常:! [remote rejected] HEAD -> refs/for/master ([3149246] missing Change-Id in commit mes ...

  8. TCP/UDP模型

    1网络接口层 MAC地址2网络互联层 IP地址3传输层 TCP/UDP端口号4应用层 应用层协议

  9. samba配置中常见错误收集.txt

    在命令行输入命令: ~$ smbclient -L \\127.0.0.1按要求输入密码后,提示出错:session setup failed: NT_STATUS_LOGON_FAILURE 这是因 ...

  10. 2. instr用法

    跟oracle中的instr用法一样: SQL> select count(*) from t where instr(title,‟oracle‟)>0; COUNT(*) ———- 5 ...