zoukankan      html  css  js  c++  java
  • TCP/IP协议族之运输层协议 ( UDP, TCP)

    UDP  User Datagram Protocol    用户数据报协议

    TCP  Transmission Control Protocol    传输控制协议

    UDP:向应用层提供无连接的、不可靠的数据通信服务。端系统使用UDP协议相互通信时,UDP协议只负责将应用程序传输人传输层的数据发送出去,但是并不保证它们能到达。如果传输中数据出错,UDP协议不负责重传,而由更高层负责。当数据正确到达后,接收端不负责确认,交由更高层负责。

    1. UDP具有以下几个特性:

        <1>. UDP信息包的头标很小,只有8字节,相对于TCP的最小20字节的头标而言,传输开销更小。

        <2>. UDP是一个无连接协议,传输数据前发送端和接收端之间不建立连接,也就不需要维护连接状态,因此一台服务器可同时向多个客户机传输相同的消息。

        <3>. UDP不能确保接收方有序地接收数据包,也不会验证接收方是否收到数据包。

        <4>. UDP的吞吐量不受拥塞控制算法的调节。在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机处理能力和网络传输带宽的限制。网络出现拥塞不会使发送速率降低。虽然UDP可靠性欠佳,但由于通信开销较小,对于一些对可靠性要求不高的应用还是很划算的。另外,如视频点播等一些应用软件对实时性要求较高、而对可靠性要求不高,UDP是理想的通信协议。

    2. UDP的报文结构。

    UDP数据报封装在IP数据报中传输,每一个UDP报文被称为一个用户数据报,分为UDP头标和UDP数据两部分。

    源端口:是16位可选字段,指出发送端进程的端口以及应答应当送达的端口。如果发送主机不提供源端口,此字段为0。当目标进程必须将一个应答发送进程的时候,源端口是必需的。

    目标端口:16位的字段,是接收进程的UDP端口。

    UDP长度:包括UDP头标和UDP数据在内的总长度,UDP长度为8位。

    UDP校验和:16位的可选字段,用于检验UDP数据包是否存在错误,如果不计算校验和,此字段应当包含一个零值,大大提高了通信效率。

    数据:发送进程所要传输的数据。

    UDP校验和与伪头标:

        IP校验和仅计算IP头标。UDP校验和包括伪头标、UDP头标和UDP数据的内容。因此UDP校验和是确定数据是否正确到达的唯一手段。

    源地址:IP报头中的发送端IP地址。

    目标地址:IP报头中的接收端IP地址。

    UDP长度:不涉及UDP伪头标的长度。

    填充字段:目的在于使伪头标长度为16比特的整数倍,用0填充。

    ---------------------------------------------------------------------------------------

    TCP:用于在不可靠的互联网络上提供可靠的端到端字节流传输服务。在一个TCP连接中,仅有两方进行彼此通信。TCP不提供广播、多播服务。TCP把发送端实体要求发送的数据流分割成适当长度的数据段,然后传给IP层,再由IP层通过网络接口层将包传送给接收端主机。

    每个TCP数据报包含一个固定字节的20字节的头(还可加一个可选部分)和若干数据字节,其总长度由通信双方的MSS(最大段长)确定。当建立TCP连接时,双方互相声明自己的MSS,从中选择较小的MSS,或直接选择默认的MSS(536字节)。MSS的选取应使得每个段封装后,其长度不超过IP分组的载荷能力(65535字节)及相应网络的MTU。超过MTU的数据包将在传输过程中被分段。

    TCP为了保证不发生数据丢失,就要对传输的数据按字节标注序号,序号保证了传送到接收端实体的数据按序接收。接收端对已成功收到的数据发回一个相应的确认(ACK, Acknowlegment);如果发送端在实际规定往返时延内未收到确认,数据会被重传。

    TCP用一个校验和函数来检验数据是否有错误,在发送和接收时都要计算校验和。

    TCP对字节流的内容不作任何解释,对字节流的解释由TCP连接双方的应用层解释。

    TCP提供的是全双工连接。全双工连接包含了两个独立的、流向相反的数据流,而且这两个数据流之间不进行显式的交互。

    由于TCP提供可靠的、面向连接的字节流传输服务,因此不可避免地增加了许多控制开销。

     1.   TCP数据段结构:

     

    序列号:主机在建立一个TCP建立时便会选择一个ISN(初始序列号),进行传输时,序列号便在ISN上不断增加。

    确认号:用来标识接收方所期望收到的下一个顺序号,也同时表示接收方已正确收到ACK之前的所有数据。

        TCP可以累积确认,即在接收多个报文段后,一次确认。

    控制位:

        URG:Urgent,为1表示紧急指针有效,为0则忽略紧急指针值。

        ACK:为1表示确认号有效,为0表示报文中不包含确认信息,忽略确认号字段。

        PSH:为1表示带有PUSH标志的数据,指示接收方应尽快将这个报文段交给应用层而不用等待缓冲区填满。

        RST:Reset,用于复位由于主机崩溃或其他非法原因出现错误的连接,即重建TCP连接。

        SYN:SYNchronize,即同步序号,为1表示连接请求,用于建立连接和使顺序号同步。

        FIN:Final,用于释放连接,为1表示发送方已经没有数据发送了,即关闭本方数据流。

    紧急指针:当发送方有紧急数据需要传送时,TCP将紧急数据插入到TCP数据段的开头,并为紧急指针设置一个正的偏移量,将紧急指针定位到紧急数据的最后一个字节。这样TCP接收端就能优先读取紧急数据,而又不影响原本数据的正常传输。

    填充字段:用于将TCP头标的长度填充为32的整数倍,为"0"。

     2.    TCP的连接

    每一条TCP连接有两个端点,叫做套接字(socket)或插口。端口号拼接到(contatenated with) IP地址即构成了套接字。

    套接字表示方法是在点分十进制的IP地址后面写上端口号,中间用冒号或逗号隔开。

    例如,IP地址为 192.2.3.4,而端口号为 80,那么套接字就是 ( 192.2.3.4: 80 )。

    即:    套接字 ::= { IP地址: 端口号 }

    每一条TCP连接唯一的被通信两端的两个端点(即两个套接字)所确定。

    即:    TCP连接 ::= { socket1, socket2 } = { ( IP1: port1 ), ( IP2: port2 )}

    3.    可靠传输的工作原理

    3.1  停止等待协议

    3.1.1 无差错情况

        A发送分组M1,发完就暂停发送,等待B的确认。B收到了M1就向A发送确认。A在收到了对M1的确认后,就再发送下一个分组M2。同样,在收到B对M2的确认后,再发 M3。

    3.1.2 出现差错

        A只要超过了一段时间仍然没有收到确认,就认为刚才发送的分组丢失了,因而重传前面发送过的分组。这就叫做超时重传。要实现超时重传,就要在每发送完一个分组设置一个超时计时器。如果在超时计时器到期之前收到了对方的确认,就撤消已设置的超时计时器。在这里,应注意三点:

        <1>. A发送完一个分组后,必须暂时保留已发送的分组的副本,在收到相应的确认后才能消除暂时保留的分组副本。

        <2>. 分组和确认分组都必须进行编号。

        <3>. 超时计时器设置的重传时间应当比数据在分组传输的平均往返时间更长一些。

    3.1.3 确认丢失和确认迟到

        A在超时计时器到期后就要重传M1,假定此时B又收到了重传的分组M1,这里应采取:

            <1>. 丢弃这个重复的分组M1,不向上层交付。

            <2>. 向A发送确认。

        A会收到重复的确认。处理:收到后就丢弃。

    通过确认和重传机制,我们就可以在不可靠的传输网络上实现可靠的通信。这种可靠传输协议就称为自动重传请求ARQ( Automatic Repeat reQuest )。

    4.    信道利用率

        停止等待协议优点是简单,缺点是信道利用率太低。

        为了提高传输效率,发送方可以不使用低效率的停止等待协议,而是采用流水线传输(连续ARQ协议和滑动窗口协议)。

    5.    TCP可靠传输的实现

    5.1  以字节为单位的滑动窗口

    5.2  超时重传时间的选择

        报文段的往返时间RTT,加权平均往返时间RTTs(平滑往返时间)

        新的RTTs = ( 1 - a ) x ( 旧的RTTs ) + a x ( 新的RTTs )  推荐a=0.125。

        超时计时器设置的超时重传时间RTO应略大于上面得出的加权平均往返时间RTTs。

        RTO = RTTs + 4 x RTTd  ( RTTd 是RTT的偏差加差平均值。)

        当第一次测量时,RTTd值取为测量到的RTT样本值的一半。在以后的测量中,使用下式:

        新的RTTd = ( 1-b ) x ( 旧的RTTd ) + b x | RTTs - 新的RTT样本 |  ,推荐b=0.25。

        如何判定此确认报文段是对先发送的报文段的确认,还是对后来重传的报文段的确认?由于重传的报文段和原来的报文段完全一样,因此源主机在收到确认后,就无法做出正确的判断,而正确的判断对确定加权平均RTTs的值关系很大。Karn提出了一个算法:在计算加权平均RTTs时,只要报文段重传了,就不采用其往返时间样本。这样得出的加权平均RTTs和RTO就较准确。 进一步修正:报文段每重传一次,就把超时重传时间RTO增大一些。

    5.3  选择确认SACK

        若收到的报文无差错,只是未按序号,中间还差一些序号的数据,那么能否设法只传送少的数据而不重传已经正确到达接收方的数据?答案是可以的。选择确认就是一种可行的处理方法。

        要建立TCP连接时,就要在TCP首部的选项中加上“允许SACK”的选项,而双方必须事先商定好。如果使用选择确认,那么原来首部中的“确认号字段”的用法仍然不变。只是以后在TCP报文段的首部中都增加了SACK选项,以便报告收到的不连续的字节块的边界。SACK并没有指明发送方应当怎样响应SACK,因此大多数的实现还是重传所有未被确认的数据块。


    source url:http://www.cnblogs.com/way_testlife/archive/2010/10/06/1844506.html

  • 相关阅读:
    Python 生产者与消费者模型
    Python 进程队列
    Python 进程
    Python Socket网络编程
    Python 异常处理
    C# .net 下载了个.dll的文件,怎么用啊?
    ScriptManager.RegisterStartupScript用法详解
    ScriptManager.RegisterStartupScript与ClientScript.RegisterStartupScript区别
    IDisposable接口
    Guid排序问题
  • 原文地址:https://www.cnblogs.com/hnrainll/p/2212253.html
Copyright © 2011-2022 走看看