最近工作中需要自己在板卡植入TCP/IP协议栈,因为毕竟单片机性能有限,完整的TCP/IP协议栈很庞大,所以只能移植经过简化的,本来已成功将LWIP协议栈移植到项目板卡中,但老大说这个协议栈写得过于繁琐,特别是在内存管理这块,不容易理解,而且我们板卡对数据的准确性要求没那么高,重点要保证能通就行,偶尔丢失一两个包都没关系,所以按此需求自写协议栈,实现UDP以及Telnet通信,目前UDP已经实现,其余功能还在慢慢增加中,通过这段时间的研究发现实现UDP并不难,最主要是要把网络通信的一些基本概念知识搞懂,搜集了很多资料,现在将自己觉得比较有用基础知识介绍如下。
以太网总体概述
"以太网"这个名字起源于一个科学假说:19世纪科学家们普遍认为光是通过一种叫以太的物质传播的。时至今日,以太的存在早就被爱因斯坦狭义相对论否定了,而以太网却成了主流的计算机网络,依旧为人类传递着光和电磁信息。
以太网(Ethernet)指的是由Xerox公司创建并由Xerox、Intel和DEC公司联合开发的基带局域网规范,是当今现有局域网采用的最通用的通信协议标准。以太网络使用CSMA/CD(载波监听多路访问及冲突检测)技术,并以10M/S的速率运行在多种类型的电缆上。以太网与IEEE802.3系列标准相类似。
包括标准的以太网(10Mbit/s)、快速以太网(100Mbit/s)和10G(10Gbit/s)以太网。它们都符合IEEE802.3。
主要有以下两种拓扑结构:
总线型:所需的电缆较少、价格便宜、管理成本高,不易隔离故障点、采用共享的访问机制,易造成网络拥塞。早期以太网多使用总线型的拓扑结构,采用同轴缆作为传输介质,连接简单,通常在小规模的网络中不需要专用的网络设备,但由于它存在的固有缺陷,已经逐渐被以集线器和交换机为核心的星型网络所代替。如下图:
总线型
星型:管理方便、容易扩展、需要专用的网络设备作为网络的核心节点、需要更多的网线、对核心设备的可靠性要求高。采用专用的网络设备(如集线器或交换机)作为核心节点,通过双绞线将局域网中的各台主机连接到核心节点上,这就形成了星型结构。星型网络虽然需要的线缆比总线型多,但布线和连接器比总线型的要便宜。此外,星型拓扑可以通过级联的方式很方便的将网络扩展到很大的规模,因此得到了广泛的应用,被绝大部分的以太网所采用。
1. 以太网工作原理
以太网采用带冲突检测的载波帧听多路访问(CSMA/CD)机制。以太网中节点都可以看到在网络中发送的所有信息,因此,我们说以太网是一种广播网络。
以太网的工作过程如下:
当以太网中的一台主机要传输数据时,它将按如下步骤进行:
1、监听信道上是否有信号在传输。如果有的话,表明信道处于忙状态,就继续监听,直到信道空闲为止。
2、若没有监听到任何信号,就传输数据
3、传输的时候继续监听,如发现冲突则执行退避算法,随机等待一段时间后,重新执行步骤1(当冲突发生时,涉及冲突的计算机会发送会返回到监听信道状态。
注意:每台计算机一次只允许发送一个包,一个拥塞序列,以警告所有的节点)
4、若未发现冲突则发送成功,所有计算机在试图再一次发送数据之前,必须在最近一次发送后等待9.6微秒(以10Mbps运行)。
2. 帧格式
以太网主要有四种帧格式,各有不同,但在每种格式的以太网帧的开头处都有64bit(8字节)的前导字符;其中,前7个字节称为前同步码(Preamble),内容是16进制数0xAA;最后1字节为帧起始标识符0xAB;它标识着以太网帧的开始,前导字符的作用是使接收节点进行同步并做好接收数据帧的准备。如下图:
前导字符过后才是各种类型的帧真正的开始;大体可分为如下四类:
2.1. Ethernet II
即DIX 2.0:Xerox与DEC、Intel在1982年制定的以太网标准帧格式,如图所示。
Ethernet II类型以太网帧的最小长度为64字节(6+6+2+46+4),最大长度为1518字节(6+6+2+1500+4)。其中前12字节分别标识出发送数据帧的源节点MAC地址和接收数据帧的目标节点MAC地址。(注:ISL封装后可达1548字节,802.1Q封装后可达1522字节)。
接下来的2个字节标识出以太网帧所携带的上层数据类型,如:
0x0800: IP协议;
0x0806: ARP协议;
0x809B:AppleTalk协议数据;
0x8138: Novell类型协议数据。
在不定长的数据字段后是4个字节的帧校验序列(Frame Check Sequence,FCS),采用32位CRC循环冗余校验对从"目标MAC地址"字段到"数据"字段的数据进行校验。
2.2. Ethernet 802.3 raw
Novell在1983年公布的专用以太网标准帧格式,如下图所示。
在Ethernet 802.3 raw类型以太网帧中,原来Ethernet II类型以太网帧中的类型字段被“总长度”字段所取代,它指明其后数据域的长度,其取值范围为:46~1500。
接下来的2个字节是固定不变的16进制数0xFFFF,它标识此帧为Novell以太类型数据帧。
2.3. Ethernet 802.3 SAP
IEEE在1985年公布的Ethernet 802.3的SAP版本以太网帧格式,如下图所示:
从上图中可以看出,在Ethernet 802.3 SAP帧中,将原Ethernet 802.3 raw帧中2个字节的0xFFFF变为各1个字节的DSAP和SSAP,同时增加了1个字节的"控制"字段,构成了802.2逻辑链路控制(LLC)的首部。LLC提供了无连接(LLC类型1)和面向连接(LLC类型2)的网络服务。LLC1是应用于以太网中,而LLC2应用在IBM SNA网络环境中。
新增的802.2 LLC首部包括两个服务访问点:源服务访问点(SSAP)和目标服务访问点(DSAP)。它们用于标识以太网帧所携带的上层数据类型,如16进制数0x06代表IP协议数据,16进制数0xE0代表Novell类型协议数据,16进制数0xF0代表IBM NetBIOS类型协议数据等。
至于1个字节的"控制"字段,则基本不使用(一般被设为0x03,指明采用无连接服务的802.2无编号数据格式)。
2.4. Ethernet 802.3 SNAP
IEEE在1985年公布的Ethernet 802.3的SNAP版本以太网帧格式,如图所示:
Ethernet 802. 3 SNAP类型以太网帧格式和Ethernet 802. 3 SAP类型以太网帧格式的主要区别在于:
2个字节的DSAP和SSAP字段内容被固定下来,其值为16进制数0xAA。
1个字节的"控制"字段内容被固定下来,其值为16进制数0x03。
增加了SNAP字段,由下面两项组成:
新增了3个字节的组织唯一标识符(Organizationally Unique Identifier,OUI ID)字段,其值通常等于MAC地址的前3字节,即网络适配器厂商代码。
2个字节的“类型”字段用来标识以太网帧所携带的上层数据类型。
3. TCP/IP协议
3.1. 简介
TCP/IP:传输控制协议/因特网互联协议,又名网络通信协议;是Internet最基本的协议,Internet国际互联网络的基础,由网络层的IP协议和传输层的TCP协议组成,TCP/IP定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准。通俗而言:TCP负责发现传输问题,一有问题就发出信号,要求重新传输,直到所有的数据安全正确的传输到目的地,而IP是给因特网的每一台联网设备规定一个地址。
它并不是TCP和IP两个协议的合称,而是指整个TCP/IP协议族,OSI(开放系统互联参考模型)将TCP/IP分为七层,实际使用我们可以将其简化为四层,如下图:
YMODEM也是一种XMODEM的实现。它包括XMODEM-1K的所有特征,另外在一次单一会话期间为发送一组文件,增加了批处理文件传输模式。
3.2. 协议内容
3.2.1. 协议相关控制字符
SOH 0x01
STX 0x02
EOT 0x04
ACK 0x06
NAK 0x15
CAN 0x18
CTRLZ 0x1A
3.2.2. 标准帧格式(128字节)
SOH |
信息包序号 |
包序号的补码 |
数据区段 |
校验和 |
起始字节 |
包号 |
取反加1 |
128 |
数据区段和 |
1k-Xmodem帧格式如下:
STX |
信息包序号 |
包序号的补码 |
数据区段 |
校验和 |
起始字节 |
包号 |
取反加1 |
1024 |
数据区段和 |
说明:
SOH 帧的开头字节,代表信息包中的第一个字节
信息包序号:对256取模所得到当前包号,第一个信息包的序号为1,而信息包序号范围 0~255;
信息包序号的补码:当前信息包号的补码;
数据区段: 数据区段的长度固定为128字节(最后一个区段数据字节数肯定小于128,由CTRLZ来填充),其内容没有任何限制,可以是文本数据或二进制数据;
算术校验和:1字节的算术校验和,只对数据区段求和后对256取模而得;
3.2.3. 传输逻辑
1> 收发双方拨号连通后,发送方等待接收方传来 NAK 信号。当第一个NAK 到达,发送方解释为开始发送第一个包;
2> 发送方一旦收到第一个 NAK,启动了传输,发送方就将数据以每次 128字节打包成帧格式传送,再等待接收方的确认信号;
3> 发送方收到接收方传来的ACK信号,解释为信息包被正确接收,并有发送下一个包的含义;
4> 发送方收到接收方传来的NAK信号,解释为请求重发同一数据包;
5> 发送方收到接收方传来的 CAN 信号,解释为请求无条件停止传输过程;
6> 发送方正常传输完全部数据,需要正常结束,发送EOT信号通知接收方。接收方用 ACK 进行确认;
7> 接收方发送CAN无条件停止传输过程,发送方收到CAN后,不发送 EOT 确认;
8> 虽然信息包是以 SOH 来标志一个信息包的起始的,但在 SOH 位置上出现的 EOT则表示数据传输结束,再也没有数据传过来;
9> 接收方首先应确认信息包序号的完整性,通过对信息包序号取补,然后和信息包序号的补码异或,结果为0表示正确,结果不为0则发送NAK请求重传;
10> 接收方确认信息包序号正确后,然后检查是否期望的序号。如果不是期望得到的信息包序号,说明发生严重错误,应该发送一个 CAN 来中止传输;
11> 对于10>情况的唯一例外,是收到的包的信息包序号与前一个信息包序号相同,此中情况,接收方简单忽略这个重复的包,向发送方发出 ACK ,准备接收下一个包。
12>接收方确认了信息包序号的完整性和是正确期望的后,只对 128 字节的数据区段进行算术和校验,结果与帧中最后一个字节(算术校验和)比较,相同发送 ACK,不同发送 NAK;
3.2.4. 超时处理
1> 接收方等待一个信息包的到来所具有的超时时限为 10 秒,每个超时后发送 NAK;
2> 当收到包时,接收过程中每个字符的超时间隔为1秒;
3> 为保持“接收方驱动”,发送方在等待一个启动字节时不应该采用超时处理
4> 一旦传输开始,发送方采用单独的1分钟超时时限,给接收方充足的时间做发送ACK 、NAK 、CAN之前的必须处理;
5> 所有的超时及错误事件至少重试10次;
3.2.5. 校验和的说明
Xmodem协议支持2种校验和,它们是累加和与CRC校验。当接收方一开始启动传输时发送的是NAK,表示它希望以累加和方式校验。当接收方一开始启动传输时发送的是字符“C”,表示它希望以CRC方式校验。
可能有人会问,接收方想怎么校验发送方都得配合吗,难道发送方必须都支持累加和校验和CRC校验?事实上Xmodem要求支持CRC的就必须同时支持累加和,如果发送方只支持累加和,而接收方用字符“C”来启动,那么发送方只要不管它,当接收方继续发送“C”,三次后都没收到应答,就自动会改为发送NAK,因为它已经明白发送方可能不支持CRC校验,现在接收方改为累加和校验和发送方通讯。发送方收到NAK就赶紧发送数据包响应。
4. TCP协议
4.1. 协议简介
为方便查询和使用板卡功能,仿照Linux终端工具开发了板卡终端平台,通过串口或网口Telnet可以操作板卡各项功能,底层代码中将板卡各项功能均做成统一格式的接口,放在一个注册表中,这样既方便上位机操作板卡,也方便了底层功能的添加和修改;终端界面如下:
TCP是一种面向连接的、可靠的、基于IP的传输层协议,面向连接意味着两个使用TCP的应用在彼此交换数据之前必须先建立一个TCP连接。当应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,TCP则把数据分割成适当长度的报文段,最大传输段大小通常受计算机连接的网络的数据链路层的最大传送单元(MTU)限制。之后TCP把数据包传给IP层,由它来通过网络将包传送给接收端的TCP层。
TCP为了保证报文传输的可靠,就给每个包一个序号,同时序号也保证了传送到接收端的数据包能被按序接收。然后接收端对已成功收到的字节发回一个相应的确认(ACK);如果发送端在合理的往返时延(RTT)内未收到确认,那么对应的数据将会被重传。
在数据正确性与合法性上,TCP用一个校验和函数来检验数据是否有错误,在发送和接收时都要计算校验和。在保证可靠性上,采用超时重传和捎带确认机制,在流量控制上,采用滑动窗口协议,协议中规定,对于窗口内未经确认的分组需要重传,在拥塞控制上,采用TCP拥塞控制算法;
4.2. TCP首部
TCP数据被封装在一个IP数据报中,如下:
下图为TCP报文数据格式,在没有选项的情况下,它通常是20个字节:
源端口号和目的端口号用于寻找发送端和接收端的应用进程,这个和UDP报文相同,这两个指加上IP首部中的源IP地址和目的IP地址唯一确定一个TCP连接。
序列号字段用来标识从TCP发送端向TCP接收端发送的数据字节流,它表示在这个报文段中的第一个数据字节。当建立一个新的连接时,握手报文中的SYN标志置1,这个握手报文中的序号字段为随机选择的初始序号ISN,当连接建立好以后发送方要发送的第一个字节序号为ISN+1。
确认号字段只有在ACK为1的时候才有用,确认号中包含发送确认的一方所期望收到的下一个序号,确认号是在上一次成功接收到的数据字节序号上加1,例如上次成功接收到对方发过来的数据序号为X,那么返回的确认号就应该为X+1。
头部长度也叫首部长度,首部长度中给出了首部的长度,以32bit也就是4字节为单位,这个字段有4bit,因此TCP最多有60字节的首部,如果没有任何的选项字段,正常的首部长度是20字节。
TCP首部中还有6个标志比特,这个6个标志位的说明如下:
窗口尺寸也就是窗口大小,其中填写相应的值以通知对方自己期望接收的字节数,窗口大小字段是TCP流量控制的关键字段,窗口大小是一个16bit的字段,因此窗口大小最大为65535字节。
16位的校验和和UDP的校验和的计算过程和原理相同,这是一个强制性的字段,校验和覆盖了整个TCP报文段,TCP首部和TCP数据;
紧急指针只有在URG置1时才有效,紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。