协议栈----资料收集整理消化吸收---阿冬专栏

(一)

1.协议栈是什么--简介

补充:

当我们学习网络协议的时候,很多朋友都将协议栈和协议弄混了。那么这次我们就来解释一下协议栈是什么。相信大家通过阅读文章后就能找到答案,现在就让我们一起来看看具体的内容吧。

协议栈

协议栈是什么?协议栈是指网络中各层协议的总和,其形象的反映了一个网络中文件传输的过程:由上层协议到底层协议,再由底层协议到上层协议.使用最广泛的是英特网协议栈,由上到下的协议分别是:应用层(HTTP,TELNET,DNS,EMAIL等),运输层(TCP,UDP),网络层(IP),链路层(WI-FI,以太网,令牌环,FDDI等)

tcp/ip协议栈

TCP/IP协议,或称为TCP/IP协议栈,或互联网协议系列.

TCP/IP协议栈

(按TCP/IP参考模型划分)

应用层 FTP SMTP HTTP ...

传输层 TCP UDP

网络层 IP ICMP ARP

链路层 以太网 令牌环 FDDI ...

包含了一系列构成互联网基础的网络协议.

这些协议最早发源于美国国防部的DARPA互联网项目.

TCP/IP字面上代表了两个协议:TCP传输控制协议和IP互联网协议.

时间回放到1983年1月1日,在这天,互联网的前身Arpanet中,TCP/IP协议取代了旧的网络核心协议NCP(Network Core Protocol),从而成为今天的互联网的基石.最早的的TCP/IP由Vinton Cerf和Robert Kahn两位开发,慢慢地通过竞争战胜了其它一些网络协议的方案,比如国际标准化组织ISO的OSI模型.TCP/IP的蓬勃发展发生在上世纪的90年代中期.当时一些重要而可靠的工具的出世,例如页面描述语言HTML和浏览器Mosaic,导致了互联网应用的飞束发展.

随着互联网的发展,目前流行的IPv4协议(IP Version 4,IP版本四)已经接近它的功能上限.IPv4最致命的两个缺陷在于:

地址只有32位,IP地址空间有限;

不支持服务等级(Quality of Service, Qos)的想法,无法管理带宽和优先级,故而不能很好的支持现今越来越多的实时的语音和视频应用.因此IPv6 (IP Version 6, IP版本六) 浮出海面,用以取代IPv4.

TCP/IP成功的另一个因素在与对为数众多的低层协议的支持.这些低层协议对应与OSI模型 中的第一层(物理层)和第二层(数据链路层).每层的所有协议几乎都有一半数量的支持TCP/IP,例如: 以太网(Ethernet),令牌环(Token Ring),光纤数据分布接口(FDDI),端对端协议( PPP),X.25,帧中继(Frame. Relay),ATM,Sonet, SDH等.

TCP/IP协议栈组成

我了解了协议栈是什么,现在就来看看它的组成。整个通信网络的任务,可以划分成不同的功能块,即抽象成所谓的 " 层" .用于互联网的协议可以比照TCP/IP参考模型进行分类.TCP/IP协议栈起始于第三层协议IP(互联网协议) .所有这些协议都在相应的RFC文档中讨论及标准化.重要的协议在相应的RFC文档中均标记了状态: "必须" (required) ,"推荐" (recommended) ,"可选" (elective) .其它的协议还可能有" 试验"(experimental) 或" 历史"(historic) 的状态.

必须协议

所有的TCP/IP应用都必须实现IP和ICMP.对于一个路由器(router) 而言,有这两个协议就可以运作了,虽然从应用的角度来看,这样一个路由器 意义不大.实际的路由器一般还需要运行许多"推荐"使用的协议,以及一些其它的协议.

在几乎所有连接到互联网上的计算机上都存在的IPv4 协议出生在1981年,今天的版本和最早的版本并没有多少改变.升级版IPv6 的工作始于1995年,目的在与取代IPv4.ICMP 协议主要用于收集有关网络的信息查找错误等工作.

现在相信大家都了解了协议栈是什么,并且对于它的结构也有所掌握了。希望本文的资料对您有所帮助。


  协议栈,英语名称为Protocol stack,又称协议堆叠,是计算机网络协议套件的一个具体的软件实现。协议套件中的一个协议通常是只为一个目的而设计的,这样可以使得设计更容易。因为每个协议模块通常都要和其他两个通信,它们通常可以想象成是协议栈中的层。最低级的协议总是描述与硬件的物理交互。每个高级的层次增加更多的特性。

协议栈----资料收集整理消化吸收---阿冬专栏_第1张图片

2.协议栈是什么--分类

  协议栈是指网络中各层协议的总和,其形象的反映了一个网络中文件传输的过程,由上层协议到底层协议,再由底层协议到上层协议。协议栈主要分为以下几种:

  OSI协议栈:OSI协议栈是由国际标准化组织为提倡世界范围的互操作性而定义的。它通常被用于其它协议栈进行比较的标准。

  TCP/IP协议组:传输控制协议/因特网协议(TCP/IP)是最早的网络协议栈之一。其中IP部分提供了一种对互联网络连接的最好定义,并且被许多厂商用于在局域或广域互联产品。

  ZigBee协议栈是在IEEE 802.15.4标准基础上建立的,定义了协议的MAC和PHY层。ZigBee设备应该包括IEEE802.15.4的PHY和MAC层,以及ZigBee堆栈层:网络层、应用层和安全服务提供层。

协议栈----资料收集整理消化吸收---阿冬专栏_第2张图片

3.协议栈是什么--应用

  协议是个标准,是约定;协议栈是协议的实现,可以理解为代码、函数库、供上层应用调用。商业化的协议栈就是给你写好了底层的代码,符合协议标准,提供给你一个功能模块给你调用。你需要关心的就是你的应用逻辑,数据从哪里到哪里,怎么存储,处理还有系统里的设备之间的通信顺序什么的。所以当你做具体应用时,不需要关心协议栈是怎么写的,里面的每条代码是什么意思。

协议栈----资料收集整理消化吸收---阿冬专栏_第3张图片

 (二)

来自牛哥的经验之谈

1,协议栈

简介

  协议栈是指网络中各层协议的总和,其形象的反映了一个网络中文件传输的过程:由上层协议到底层协议,再由底层协议到上层协议。使用最广泛的是英特网协议栈,由上到下的协议分别是:应用层(HTTP,TELNET,DNS,EMAIL等),运输层(TCP,UDP),网络层(IP),链路层(WI-FI,以太网,令牌环,FDDI等),物理层。

协议栈 Protocol Stack ↑

  如果不参考下面进行数据交换的协议或通信过程的讨论,那么就不可能讨论计算机的互联。对协议的任何讨论通常都会牵涉到与开放式系统互联(OSI)协议栈的比较。OSI协议栈定义了厂商们如何才能生产可以与其它厂商的产品一起工作的产品。然而,由于缺乏工业界的承认,今天,OSI更象是一个模型,而不是一个被接受的标准。这是因为许多公司已经在他们的产品中实现了另外一些协议。

  协议定义与其它系统通信的方式。它描述信号的时序和通信数据的结构。在协议栈的较低层定义了厂商们可以遵循规则以使他们的设备可以与其它厂商的设备进行互联。较高层定义如何管理不同类型的通信会话,用户应用程序如何才能相互操作。你在协议栈中走得越高,协议也越复杂。

  让我们利用OSI标准来比较厂商的操作系统及产品间网络互联和互操作性。在这个OSI模型中,在协议栈中有七层,每个都在不同的硬件和软件级别进行工作。你可以检查协议栈的每一层来观察系统是怎样在局域网(LAN)上进行通信的。互联或协议栈的OSI模型如图P-17所示。

  如以前所述,许多厂商并不完全跟随OSI协议栈。他们使用很接近OSI协议栈的其它协议栈,或者将一些独立的协议组合成一个协议组。图P-18对一些最流行的协议栈进行了比较。使用一种协议栈的产品不能与使用另外一种协议栈的产品直接相连或相互操作。然而,使用不同的“封装”技术和协议转换,是可能在它们之间做到一些级别的互操作性的。下面列出了一些主要的协议栈:

  OSI协议栈:OSI协议栈是由国际标准化组织(ISO)为提倡世界范围的互操作性而定义的。它通常被用于其它协议栈进行比较的标准。

  NetWare SPX/IPX协议:NetWare串行分组交换/网间分组交换(SPX/IPX)协议,是由NovellNetWare使用的一种本质性协议(nativeprotocol)。它源于Xerox网络系统(XNS)协议栈。

  TCP/IP协议组:传输控制协议/因特网协议(TCP/IP)是最早的网络协议栈之一。它最初是由美国国防部为将多厂商网络产品连接在一起而实现的。其中IP部分提供了一种对互联网络连接的最好定义,并且被许多厂商用于在局域或广域互联产品。

  AppleTalk协议:AppleTalk协议是由Apple Computer为互联Apple Macintosh系统而定义的。

  IBM/Microsoft协议组:IBM和Microsoft进行互联的产品通常是结合在一起的,这是因为这两个公司联合起来开发使用他们的产品,例如,L管理器和OS/2。

2,协议栈开发步骤经验

一,阅读协议栈相关文档

    关于单个协议的定义,权威的自然是IETF(互联网工程任务推进组织)的"rfc"文档,虽然是一大堆的英文(呵呵,我英文也一般),开始不太看的明白,不过没关系,先去网络上用"baidu"或则"google"搜索一下关于你要做的这个协议的中文说明,虽然绝大数介绍都很肤浅,但这么做的在于去了解该协议的目的和用途,心中有个大的概念,而后在大致的阅读下该协议"rfc"文档的大体描述和结构。

    需要说明的是在大多数情况下,一个完整的协议栈都有好几个协议组成,所以也有1个或若干个"rfc"文档要去学习和了解,但切记不用把所有"rfc"文档都读的相当仔细和完全明白后再去做,我们的目的在于只把握协议栈的框架和大概信息。

    所以,这个阶段是基础准备阶段。

 

二,设计协议栈结构

    这个阶段也是最核心、最重要的一个阶段,可以说,开发成功与否的关键也全在这个阶段。我们在第一个阶段的基础上,明白了要开发的协议栈的功能及其相关协议后,我们就要来设计这个协议栈框架的实现,一般有注意如下几方面:

    1,功能性:这个很自然,如能实现功能还做什么

    2,可扩展:协议栈最好划分出内核和外围模块,利于将来扩展和维护

    3,模块独立:协议栈内核和外围模块尽量独立,减少耦合

这个阶段虽然说起来容易,但做起来去要看个人的能力和水平,包括代码的机构、风格、易维护、易移植、稳定、健壮性等等。所以,如果连基本程序都写不好,没有好的代码风格和没有把握大结构能力的,最好还是请别人帮忙。

注释:协议栈的设计要看协议栈的特点,比如有的协议栈是对称的(比如rtsp流控协议),有些是不对称的(比如http协议),各有各特点,所以在把握大结构的同时要针对各自的特点来设计。

 

三,编码开发

    框架完成后,开始丰满核心模块和构建基本的外围模块。通常这阶段需要搭建好开发环境,便测试便修改。

注释:很重要的工作,ethereal(抓包软件),做协议这个是一定要用熟的。

 

四,测试与维护

    基本上到这个阶段,协议栈的开发工作就OK了,剩下的就是测试、维护,调整代码,加强协议栈的稳定性和健壮性。

 

五,后记

    由于文字表达上的局限和本人水平的问题,上述只是简要描述了一下开发协议栈的一般常规步骤,算是对自己的一个总结,也希望对读者有所帮助,不当之处,请多包含。

 

个人已做过的协议栈(简要说明):

1, SIP

   会话发起协议,关联SDP/RTP/RTCP等协议

2, TR069

   终端网管协议,关联HTTP/SOAP/XML/TR-111(STUN NAT穿越)/TR-106(外围数据模型)

3, 流控

   多媒体流控协议,管理RTSP/RTP/SDP/MP2T等

 

(三)

简析开原协议栈

在开源系统中,可能一些协议栈的使用会稍许不同,那么下面我们就讲解了几个常用的开源协议栈,来为大家详细讲解和对比一下。具体内容,还请大家从下文来了解吧,首先让我们看看BSD TCP/IP协议栈。

1、BSD TCP/IP协议栈

BSD栈历史上是其他商业栈的起点,大多数专业TCP/IP栈(VxWorks内嵌的TCP/IP栈)是BSD栈派生的.这是因为BSD栈在BSD许可协议下提供了这些专业栈的雏形,BSD许用证允许BSD栈以修改或未修改的形式结合这些专业栈的代码而无须向创建者付版税.同时,BSD也是许多TCP/IP协议中的创新(如广域网中饿拥塞控制和避免)的开始点.

2、uC/IP

uC/IP是由Guy Lancaster编写的一套基于uC/OS且TCP/IP开源协议栈,亦可移植到其它操作系统,是一套完全免费的、可供研究的TCP/IP协议栈,uC/IP大部分源码是从公开源码BSD发布站点和KA9Q(一个基于DOS单任务环境运行的TCP/IP协议栈)移植过来.uC/IP具有如下一些特点:带身份验证和报头压缩支持的PPP协议,优化的单一请求/回复交互过程,支持IP/TCP/UDP协议,可实现的网络功能较为强大,并可裁减.UCIP协议栈被设计为一个带最小化用户接口及可应用串行链路网络模块.根据采用CPU、编译器和系统所需实现协议的多少,协议栈需要的代码容量空间在30-60KB之间.

3、LwIP

LwIP是瑞士计算机科学院(Swedish Institute of Computer Science)的Adam Dunkels等开发的一套用于嵌入式系统的开放源代码TCP/IP协议栈.LwIP的含义是Light Weight(轻型)IP协议,相对于uip.LwIP可以移植到操作系统上,也可以在无操作系统的情况下独立运行.LwIP TCP/IP实现的重点是在保持TCP协议主要功能的基础上减少对RAM的占用,一般它只需要几十K的RAM和40K左右的ROM就可以运行,这使LwIP协议栈适合在低端嵌入式系统中使用.LwIP的特性如下:支持多网络接口下的IP转发,支持ICMP协议 ,包括实验性扩展的的UDP(用户数据报协议),包括阻塞控制,RTT估算和快速恢复和快速转发的TCP(传输控制协议),提供专门的内部回调接口(Raw API)用于提高应用程序性能,并提供了可选择的Berkeley接口API.

4、uIP

uIP是专门为8位和16位控制器设计的一个非常小的TCP/IP栈.完全用C编写,因此可移植到各种不同的结构和操作系统上,一个编译过的栈可以在几KB ROM或几百字节RAM中运行.uIP中还包括一个HTTP服务器作为服务内容.许可:BSD许用证

5、TinyTcp

TinyTcp 栈是TCP/IP的一个非常小和简单的实现,它包括一个FTP客户.TinyTcp是为了烧入ROM设计的并且现在开始对大端结构似乎是有用的(初始目标是68000芯片).TinyTcp也包括一个简单的以太网驱动器用于3COM多总线卡

选择一个开源协议栈可以从四个方面来考虑:

一个是是否提供易用的底层硬件API,即与硬件平台的无关性;

一个是与操作系统的内核API.协议栈需要调用的系统函数接口是否容易构造,

另一个对于应用支持程度.

最关键的是占用的系统资源是否在可接受范围内,有裁减优化的空间否?

其中,BSD 栈可完整实现TCP/IP协议,但代码庞大,70KB-150KB之间,裁减优化有难度,uIP和TinyTcp代码容量小巧,实现功能精简,限制了在一些较高要求场合下的应用,如可靠性与大容量数据传输.

LwIP和uC/IP是同量级别的两个开源协议栈,两者代码容量和实现功能相似,LwIP没有操作系统针对性,它将协议栈与平台相关的代码抽象出来,用户如果要移植到自己的系统,需要完成该部分代码的封装,并为网络应用支持提供了API接口的可选性.uC/IP协议最初是针对uC/OS设计,为方便用户移植实现,同样也抽象了协议栈与平台相关代码,但是协议栈所需调用的系统函数大多参照uC/OS内核函数原型设计,并提供了协议栈的测试函数,方便用户参考,其不足在于该协议栈对网络应用支持不足.

根据以上分析,从应用和开发的角度看,似乎LWIP更得到了网上很多朋友使用的青睐;uC/IP在文档支持与软件升级管理上有很多不足,但是它最初是针对UC/OS而设计,如果选用UC/OS作为软件基础的话,在系统函数构造方面有优势.当然你选择其他操作系统的话,可参照OS_NULL文件夹下的文件修改. 以上的这些开源协议栈也并非免费,拿来就可以用,据我所知,UC/OS的母公司推出UC/OS-TCP/IP花了6人*2年的工作量,国内某公司使用LWIP作为移植的参照,花了4-5人*2年的工作量来测试与优化协议,使用商用TCP/IP栈的高费用就不足为奇了. 作为广大的爱好者学习而言,如果只是跑跑原型,实验一下效果,以上的几种开源协议栈都提供了测试的例子,应该是不错的选择.

个人的看法:LWIP可优先考虑,至少网上有很多的人一块研究,参考的资料较多;UC/IP其次,如果你想深入学习TCP/IP的话,移植UC/IP是一种挑战性的工作,它尚需完善.


(四)

TCP/IP协议栈

TCP/IP是互联网的核心协议,也是大多数网络应用的核心协议。就前面一段时间面试中问到的TCP/IP问题,这里给出一个简单的小结。
 
TCP由RFC793、RFC1122、RFC1323、RFC2001、RFC2018以及RFC2581定义。
 
(1) TCP概述
a. TCP提供的是面向连接的全双工服务
TCP所有的数据会匹配到由源地址,目的地址,源端口,目的端口构成的一个TCP连接之上。TCP连接是一种需要建立的资源,可以通过之后会讲到的握手机制来完成。UDP是一种基于尽力而为机制的协议,不存在UDP连接资源的建立,资源的处理往往由应用层协议代劳了。
 
b. TCP是提供的可靠服务。
TCP有确认机制来保证数据包的可靠到达,
TCP有CRC校验机制来保证数据包的无差错性,UDP的CRC是可选的,
TCP会重新排序乱序的数据包和丢弃重复的数据,
TCP能够提供流量控制机制,使用滑动窗口算法,
TCP能提供拥塞控制与恢复机制,存在多种TCP拥塞控制模型,
TCP能协商发送的数据报文长度。
 
TCP报头。
    0                   1                   2                   3   
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |          Source Port          |       Destination Port        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                        Sequence Number                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Acknowledgment Number                      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Data |           |U|A|P|R|S|F|                               |
   | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
   |       |           |G|K|H|T|N|N|                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |           Checksum            |         Urgent Pointer        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Options                    |    Padding    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                             data                              |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                            TCP Header Format
 
对于TCP头的标记位,SYN标记只在三次握手(或四次握手)的时候的被置位,ACK标记会在握手之后所有的TCP报文中被置位。当然也有一些特殊情况,比如有些情况下RST报文不会置位ACK。
这些规则也许在配置复杂的ACL中有用。
 
(2) TCP协议栈的状态机 (摘自RFC793)
 
 
a. TCP连接的建立。TCP连接的建立有主动打开,被动打开以及同时打开三种情况。
三次握手比较清楚,要强调的是ISN,就是初始序列号的选择问题,序列号是32位的,针对不同的OS,初始序列号的选择往往也是有规律的。
 
TCP传输的最大报文长度也是在三次握手中协商的。具体说是在也仅在SYN报文中协商的。MSS = MTU - ip_header_len - tcp_header_len。MSS这里也是为了防止分片,提高网络带宽利用率。
 
TCP三次握手中,最后一个报文ACK,不需要再有额外的确认机制,如果这个ACK在网络中丢弃了,TCP协议栈也有其他的机制来处理。
除了三次握手,还有一种很特殊的应用情况,就是TCP两端同时打开的情况(发送syn),这种情况没有描述在上面的状态机中。
举例子来说,A通过源端口7777发起到B的目的端口8888的连接的同时,B也通过源端口8888发起对A的目的端口7777的TCP连接。
 
b. TCP连接的关闭
TCP连接的关闭也有主动关闭,被动关闭和同时关闭三种情况,这三种情况在上面的TCP状态机中都有描述。
TCP连接的关闭需要报文四次交互,因为TCP是一个全双工的服务,所以每个方向的连接都关闭后,TCP的连接才是完整的拆除。
状态机中,主动关闭和同时关闭最后都会进入到一个TIME_WAITE状态。针对TCP主动关闭的最后一个报文应该是ACK,确认对端的FIN报文。这个状态的概念是该TCP连接的资源并没有完全释放,因为还要确保最后一个ACK报文能够无误的到达对端,确认对端的FIN,否则就仍然要重传ACK。
这个等待的过程(或者资源没有完全释放的过程)需要等待2MSL时间(考虑报文一次往返)。MSL是最大报文生存时间,RFC793中为2分钟,根据不同的TCP实现,一般是30s或者1分钟。
 
所以在TIME_WAITE状态内,该TCP连接所使用的端口和连接资源,不能被继续使用。但是很多TCP实现并没有这个限制,只要新的TCP连接所使用的ISN大于TIME_WAITE状态TCP连接所使用的最后序号即可。实现中往往使用
new ISN = latest ISN in time_waite + 128000
 
 
IP报文的最大生存时间是TTL值,TCP报文的最大生存时间是MSL,二层上没有报文最大生存时间的概念,存在风暴的可能。
 
(3) TCP的滑动窗和定时器
a. TCP的报文确认机制。
TCP使用的是滑动窗口机制来发送数据流,所以TCP协议允许连续发送多个TCP分组而不等待对端的确认。 所以发送的分组数据和确认不是一对一的关系。
TCP中,对数据的确认往往是延迟的,一般情况是两个TCP数据对应一个确认,在时延定时器没有溢出的情况下。如果时延定时器溢出了,那么自然也会发送确认报文。
但是,针对存在交互大量微小报文的TCP应用,过于频繁的确认会导致网络利用率的低效,所以TCP支持一种Nagle算法。
 
b. 延时定时器
当TCP收到报文时候,启动延时定时器,比如200ms。
 
c. Nagle算法
TCP连接上只能存在一个未被确认的微小报文(41字节的TCP报文),在该确认到达前,TCP仅仅收集微小报文,当确认到达后,以一个分组的形式发出去。
当然,某些应用需要关闭Nagle算法。
 
d. 滑动窗口机制
窗口合拢(左移):在收到对端数据后,自己确认了数据的正确性,这些数据会被存储到缓冲区,等待应用程序获取。但这时候因为已经确认了数据的正确性,需要向对方发送确认响应ACK,又因为这些数据还没有被应用进程取走,这时候便需要进行窗口合拢,缓冲区的窗口左边缘向右滑动。注意响应的ACK序号是对方发送数据包的序号,一个对方发送的序号,可能因为窗口张开会被响应(ACK)多次。
 
窗口张开(右移):窗口收缩后,应用进程一旦从缓冲区中取出数据,TCP的滑动窗口需要进行扩张,这时候窗口的右边缘向右扩张,实际上窗口这是一个环形缓冲区,窗口的右边缘扩张会使用原来被应用进程取走内容的缓冲区。在窗口进行扩张后,需要使用ACK通知对端,这时候ACK的序号依然是上次确认收到包的序号。
 
窗口收缩,窗口的右边缘向左滑动,称为窗口收缩,Host Requirement RFC强烈建议不要这样做,但TCP必须能够在某一端产生这种情况时进行处理。
 
e. 重传定时器
目的是为了获得对端的确认报文。如果多次重传仍然没有获得确认,则会发送复位报文RST。
 
这里我们再来看一下TCP的三次握手。
A(发起端) ---> syn ---> B(服务器)
A(发起端) <--- syn/ack <--- B(服务器)
A(发起端) ---> ack    ?   B(服务器)
如果TCP客户端A的最后一个ACK丢失了,TCP服务器B没有收到,会是一种什么情况?
这个时候A已经进入到了Establish状态,然而B还只是Syn_Recev状态,所以服务器会重传syn/ack报文,只到连接的最终建立。但是客户端A已经到建立状态了,所以A是有可能发送TCP数据给服务器B的。
所以TCP的两端,最终状态机是有可能不一致的。
 
后面会详细讲述重传和拥塞控制机制。
 
f. 坚持定时器
由于TCP没有对ACK的确认机制,所以当接收端窗口从0恢复到一定值的时候,如果接收端发给发送端的ACK报文(标识窗口大小)丢失了,发送端就永远不知道接收端的窗口恢复情况了。
所以发送端会定时发送带一个字节的ACK给接收端,查看接收端的确认报文中的窗口信息。
 
g. 保活定时器
由于物理原因,处于IDLE状态的TCP连接一端崩溃的时候,TCP有保活机制来判断对端是否仍然工作。这个设计存在争议,也许应用层应该实现该功能。RFC1122中有描述,保活定时器默认是关闭的。下面截取了一些RFC描述。
Implementors MAY include "keep-alives" in their TCP implementations, although this practice is not universally accepted.  If keep-alives are included, the application MUST be able to turn them on or off for each TCP connection, and they MUST default to off.
 
 
(4) TCP拥塞控制算法:慢启动、拥塞避免、快速重传和快速恢复
针对拥塞控制,主要有四种模型,即TCP TAHOE,TCP RENO,TCP NEWRENO和TCP SACK。TCP TAHOE模型是最早的TCP协议之一,它由Jacobson提出。
 
Jacobson观察到,TCP报文段(TCP Segment)丢失有两种原因,其一是报文段损坏,其二是网络阻塞,而当时的网络主要是有线网络,不易出现报文段损坏的情况,网络阻塞为报文段丢失的主要原因。针对这种情况,TCP TAHOE对原有协议进行了性能优化,其特点是,在正常情况下,通过重传计时器是否超时和是否收到重复确认信息(dupack)这两种丢包监测机制来判断是否发生丢包,以启动拥塞控制策略; 在拥塞控制的情况下,采用慢速启动(Slow Start)算法和“拥塞避免”(Congestion Avoidance)算法来控制传输速率。 1990年出现的TCP Reno版本增加了“快速重传 ”(Fast Retransmit)、“快速恢复”(Fast Recovery)算法,避免了网络拥塞不严重时采用“慢启动”算法而造成过度减小发送窗口尺寸的现象,这样TCP的拥塞控制就主要由这4个核心算法组成。 
a. 超时与重传
RTT的计算与RTO的计算
 
b. 慢启动和拥塞避免算法
慢启动算法的目的是为了保证TCP发送方发送分组的速率应该匹配收到该分组确认报文的速率,这样的设计能够应用于低速链路的广域网应用。为了实现慢启动机制,为TCP连接增加了一个新的窗口,拥塞窗口cwnd,该窗口初始化为一个报文段(非一个字节,而是一个TCP最大传输报文段大小,MSS)。这样一个方向上的TCP连接有两个窗口,一个是接收窗口用于接收方的流量控制,一个是拥塞窗口用于发送方的流量控制。发送方以这两个窗口中的小值作为方式上限。
 
慢启动算法:指数算法,cwnd默认为1,当收到一个ack确认时候,cwnd增加为2,当收到两个ack确认时候,cwnd增加为4,接着8,...
 
拥塞避免算法的目的,是为了防止中间路由器由于网络拥塞引起的数据包超时或者丢包。拥塞避免算法需要用到两个变量,一个是cwnd窗口大小,一个是ssthresh慢启动阈值,对于一个给定的初始连接,cwnd为1,ssthresh为65535。
当拥塞发生(超时或者重复确认),当拥塞发生时候,ssthresh被设置为cwnd和接收窗口中小值的一半,如果是超时引起的拥塞,则cwnd设置为1。
 
拥塞避免算法:如果cwnd大于ssthresh,每收到一个数据报文的确认,cwnd=cwnd+1/cwnd,cwnd窗口大小单位仍然是mss。
 
拥塞避免算法其实是和慢启动配合使用的。cwnd和ssthresh都是动态的值,虽然初始值为1和65535。
当真正拥塞发生的时候,如果是超时或重复ack引起的拥塞,ssthreash会置为cwnd和接收窗口大小的一半,cwnd会降为1,然后执行慢启动算法,直到cwnd大于ssthresh的时候,执行拥塞避免算法;
在慢启动算法期间和拥塞避免算法期间,TCP的发送速率都是在增长的,只是一个是指数增长方式,一个是线性增长方式。
 
 
c . 快速重传和快速恢复算法
TCP连接中有两种情况会引起重复的ack,一种是乱序报文,一种是丢包。
 
快速重传:当发送方收到三个重复的ack后,不会进入慢启动状态,而是立刻重传丢失的报文。因为只有接收方收到新的报文段的时候,才会发送重复的ack,这表明TCP连接上仍然有数据流动,所以应该避免使用慢启动降速。
 
快速恢复:
第一步,当收到第三个重复的ack的时候,ssthresh设置为当前cwnd的一半,重传丢失的报文。设置cwnd为ssthresh加上3倍的报文段大小(cwnd=cwnd/2 + 3)。
第二步,每收到一个重复的ack,cwnd增加1并发送一个分组。
第三步,当下一个确认新数据的ack到达的时候,设置cwnd为上面第一步中ssthresh值,这个ack应该是对重传报文的确认,同时也是对丢包后面的中间报文的确认。
 
最后,在收到三个重复ack的情况下,速度减半。
 
快速重传算法首次出现在4.3BSD的Tahoe版本,快速恢复首次出现在4.3BSD的Reno版本,也称之为Reno版的TCP拥塞控制算法。
 
可以看出Reno的快速重传算法是针对一个包的重传情况的,然而在实际中,一个重传超时可能导致许多的数据包的重传,因此当多个数据包从一个数据窗口中丢失时并且触发快速重传和快速恢复算法时,问题就产生了。因此NewReno出现了,它在Reno快速恢复的基础上稍加了修改,可以恢复一个窗口内多个包丢失的情况。具体来讲就是:Reno在收到一个新的数据的ACK时就退出了快速恢复状态了,而NewReno需要收到该窗口内所有数据包的确认后才会退出快速恢复状态,从而更一步提高吞吐量。
 
SACK就是改变TCP的确认机制,最初的TCP只确认当前已连续收到的数据,SACK则把乱序等信息会全部告诉对方,从而减少数据发送方重传的盲目性。比如说序号1,2,3,5,7的数据收到了,那么普通的ACK只会确认序列号4,而SACK会把当前的5,7已经收到的信息在SACK选项里面告知对端,从而提高性能,当使用SACK的时候,NewReno算法可以不使用,因为SACK本身携带的信息就可以使得发送方有足够的信息来知道需要重传哪些包,而不需要重传哪些包。
 
(5) TCP的应用
前几天和公司做防火墙限速的同事聊天, 我们公司新的防火墙限速实现方案就用到了TCP窗口机制. 作所周知, QoS除了分类,测速,队列还有调度一类的借助硬件的算法以外,在基于缓存或者丢包的限速基础上,最好还要降低TCP端到端的真正发送的速率,否则容易引起TCP的一系列拥塞控制动作。我们软件新的设计,就是通过修改ACK方向的通告窗口大小,来控制发送发的速率,能够在限速的基础上,同时降低发送方的发送速率。

本文出自 “jasonccie” 博客,请务必保留此出处http://jasonccie.blog.51cto.com/2143955/422966



(五)sip协议栈

在开源系统中,也是比较常见SIP协议栈的使用。那么这里我们就来讲述一下开元的SIP协议栈都有哪些吧。希望本文的总结和介绍能够让大家对此有一定的了解。好了,现在就来看正文内容吧。

开源的SIP协议栈-Vocal、OSIP

SIP是由IETF提出的一套用户IP电话的通信协议,它用来建立,改变和终止基于IP网络的用户间的呼叫.该协议建立在SMTP(简单邮件传送协议)和 HTTP(超文本传送协议)等协议基础之上.为了提供电话业务它还需要结合其他几种不同的标准和协议:特别是需要确保传输(RTP),与当前电话网络的信 令互连,能够确保语音质量(RSVP),能够提供目录(LDAP),能够鉴权用户(RADIUS)等等.

由于是计算机界提出的一项电话标准,因此它显露出许多计算机业界的许多特点,比如,它尽可能的大量采用现有的协议,而不是重建标准,如HTTP、 LDAP、RADIUS等,都是技术成熟、应用广泛的协议标准.其次,就是它的开发较其他协议栈(如它的竞争协议H.323)难度较低,而且,相关的开源 项目也比较多,如VOCAL、OSIP都是比较成熟的、可商业化的SIP协议栈.

VOCAL(即Vovida开源通信应用程序库)它是由Vovida社区开发的一套SIP协议栈,OSIP则是由老牌开源社区GNU组织开发的一款SIP协议栈软件,下面对这两个协议栈进行一下简单的比较:

协议栈----资料收集整理消化吸收---阿冬专栏_第4张图片

开源的H.323协议栈-OpenH323

H.323和SIP一起,并成VOIP领域的两大标准.不同的是SIP是由计算机界(IETF)定义的,而H.323则由电信界(ITU)定义的.从应用 上来说,SIP更适合企业应用,而H.323比较适合电信级应用.从开发的难度来说,H.323远比SIP复杂,如果要从头做起的话,其开发周期将会非常 久.不过,有了OpenH323,一切都不一样了,我们完全可以在短期内做出一套电信级的VOIP系统.

OpenH323是通信领域名气最大的一款开发源代码的通信协议栈软件,该项目是澳大利亚的EquivalencePtyLtd公司组织开发的,它从 1998 年开始,到了2000 年底基本的H.323 协议框架已经实现,主要是免费面向所有想从事VOIP 和网络视频传输的软件开发商使用,这个协议库是完全符合H.323 协议的,能和任何符合该协议的软件进行视频和语音的通讯,例如Microsoft 的NetMeeting等.很多商业的H.323协议栈就是基于OpenH323基础开发的.

OpenH323的优势在于它比较完整的实现了ITU关于H.323的建议,可以实现基于IP的各种电话应用,包括语音、视频、会议以及传真等.通过该协 议栈,我们很容易的就可以定制出自己需要的包括终端、网守、网关或MCU等各种H.323实体.而且,它不需要任何付费,对商业用户和个人开发者来说都具 有很大的诱惑力.

OpenH.323支持但前流行的各种平台,包括Linux、Windows和MacOS和Unix,编程语言采用了面向对象的C++语言.关于它的具体技术细节,请参考卢政的《如何成功的运用OPENH323来开发商业的H.323协议栈》.

总结

通信软件开源的目的之一就是降低通信技术的门槛,普及通信知识,让通信行业的一些核心技术能被更多的人掌握、运用,同时,也可以减少一些通信项目重复开发 的投入,因此,意义非常重大.但是,目前通信行业的开源项目数量有限,能真正被人利用的更是屈指可数.因此,需要有更多的通信专用人士投身这一领域,使开 源思想在通信领域也能落地生根.



(六)doubango开源框架中封装的一些协议栈讲解

????????后续更新………………




你可能感兴趣的:(协议栈,协议栈)