小言_互联网的博客

网络通信--协议设计

708人阅读  评论(0)

1 介绍

1.1 定义

  • 通信协议:两个节点间信息交换的规则语法。
    类比的话,国人间语言交流,普通话就是通信协议。

  • 常见的有tcp,udo,http,sip等常见协议。

  • 其中 7层 OSI 模型中应用层,开发者可以根据应用业务逻辑自定义协议

  • 自定义协议时需要考虑确定报文长度的方式
    (1)基于定界符(Delimiter-based):消息的结束由一个唯一的标记(unique marker)指出,即发送者在传输完数据后显式添加的一个特殊字节序列。这个特殊标记不能在传输的数据中出现。比如 EOF
    (2)显式长度(Explicit length):在变长字段或消息前附加一个固定大小的字段,用来指示该字段或消息中包含了多少字节。比如 TLV

1.2 帧、数据报、数据包的区别和联系

  • 数据帧(Frame):就是数据链路层的协议数据单元,它包括三部分:帧头,数据部分,帧尾。其中,帧头和帧尾包含一些必要的控制信息,比如同步信息、地址信息、差错控制信息等;数据部分则包含网络层传下来的数据,比如ip数据包。
  • 数据包(Packet):TCP/IP协议通信传输中的数据单位,处于网络层,在局域网中,“包”是包含在“帧”里的。
  • 数据报(Datagram):多用于网络层以上,面向无连接的数据传输,工作过程类似于报文交换。采用数据报方式传输时,被传输的分组称为数据报。
  • 一般说来,数据链路层发出的数据包称为frame,地址是链路层的地址,如mac地址;网络层发出的数据包称为packet,地址是网络层地址,如ip地址;传输层发出的数据包称为segment/datagram,地址是传输层地址,如TCP的端口号。
  • 二层的PDU叫做Frame;
    IP的叫做Packet;
    TCP的叫做Segment;
    UDP的叫做Datagram。

2 TLV

2.1 TLV介绍

  • TLV: TLV是指由数据的类型Tag,数据的长度Length,数据的值Value组成的结构体,几乎可以描任意数据类型,TLV的Value也可以是一个TLV结构,正因为这种嵌套的特性,可以让我们用来包装协议的实现。

2.2 TLV优缺点

  • 优点:可扩展性、简单易学、 跨语言特性
  • 缺点:因为其增加了2个额外的冗余信息,tag 和len,特别是如果协议大部分是基本数据类型int ,short, byte. 会浪费几倍存储空间。另外Value具体是什么含义,需要通信双方事先得到描述文档,即TLV不具备结构化和自解释特性。
  • 跨语言特性
    java或PHP的语言,没有无符号类型,与C/C++语言不同,会导致负数解析失败。对使用类型做了强制性约束。虽然带来了约束,但是带来通用型和简洁性,和跨语言性,于是有了一个类型(type)规范

2.3 定长不定长

  • 描述Value部分所占字节的个数,编码格式分两类:定长方式(DefiniteForm)和不定长方式(IndefiniteForm),其中定长方式又包括短形式与长形式。
  • 短形式:

    字节第7位为0,表示Length使用1个字节即可满足Value类型长度的描述,范围在0~127之间的。
  • 长形式:

    即Value类型的长度大于127时,Length需要多个字节来描述,这时第一个字节的第7位置为1,0~6位用来描述Length值占用的字节数,然后直将Length值转为byte后附在其后,如: Value大小占234个字节(11101010),由于大于127,这时Length需要使用两个字节来描述,10000001 11101010

2.4 CRC校验

2.4.1 介绍

CRC(循环冗余校验)校验确保没有字节跳变发生

2.4.2 CRC在线计算

(1)http://www.ip33.com/crc.html
(2)https://www.lammertbies.nl/comm/info/crc-calculation.html

2.4.3 MODBUS协议

  • 上位机须按照MODBUS协议的命令格式发送数据(包括计算的CRC值),从机才能正确辨识数据。若无CRC值,从机将返回含有错误号的应答包,不会得到正确结果。标准的做法,发送前计算CRC值并一起发送,接收后也计算CRC值并与接收的校验码对比是否相等,以辨别数据是否准确。
  • 参数模型:CRC 16/modbus
  • 校验位计算
/*
* 函数名 :CRC16
* 描述 : 计算CRC16
* 输入 : ptr---数据,len---长度
* 输出 : 校验值
*/
UINT16 CRC16(UINT8 *ptr, UINT16 len)
{
    unsigned char i;
    unsigned short crc = 0xFFFF;
    if (len == 0) {
        len = 1;
    }
    while (len--) {
        crc ^= *ptr;
        for (i = 0; i<8; i++)
        {
            if (crc & 1) {
                crc >>= 1;
                crc ^= 0xA001;
            } else {
                crc >>= 1;
            }
        }
        ptr++;
    }
    return(crc);
}
unsigned short UmUtil::Crc16(const unsigned char* buf, int count)
{
    uint16_t crc = 0xffff;
    while(count > 0)
    {
        crc = (crc >> 8) ^ CRC16_Table[(crc & 0xff) ^ *(buf++)];
        count--;
    }
    return crc;
}

2.5 解析步骤

tlv报文的格式: [帧头] [Tag] [Length] [Value] [CRC校验和] (这里我用的CRC校验和是16位的所以占两个字节)

参考

1、通信协议之序列化
2、看懂通信协议:自定义通信协议设计之TLV编码应用
3、应用层通信协议开发浅析
4、浅谈自定义通讯协议——TLV
5、swoole学习笔记(五)网络通信协议设计 – EOF结束符协议和固定包头+包体协议
6、浅谈基于TCP和UDP的协议设计
7、TLV协议——实现封包与解析
8、TLV-简单的数据传输协议
9、【通信协议】帧、数据报、数据包的区别和联系
10、报文、帧、数据包等的区别
11、TLV简介以及c语言实现装包与解析–好
12、通信:成帧与解析
13、浅谈基于TCP和UDP的协议设计
14、关于modbus rtu协议的CRC(循环冗余校验)在线计算
15、Modbus通信CRC16校验程序


转载:https://blog.csdn.net/qq_38880380/article/details/102489550
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场