zoukankan      html  css  js  c++  java
  • tcp/ip详解(转)

    与UDP不同的是,TCP提供了一种面向连接的、可靠的字节流服务。TCP协议的可靠性主要有以下几点保障:

          (1)应用数据分割成TCP认为最适合发送的数据块。这部分是通过“MSS”(最大数据包长度)选项来控制的,通常这种机制也被称为一种协商机制,MSS规定了TCP传往另一端的最大数据块的长度。值得注意的是,MSS只能出现在SYN报文段中,若一方不接收来自另一方的MSS值,则MSS就定为536字节。一般来讲,在不出现分段的情况下,MSS值还是越大越好,这样可以提高网络的利用率。

          (2)重传机制。设置定时器,等待确认包。

          (3)对首部和数据进行校验。

          (4)TCP对收到的数据进行排序,然后交给应用层。

          (5)TCP的接收端丢弃重复的数据。

          (6)TCP还提供流量控制。(通过每一端声明的窗口大小来提供的)

    1.TCP/IP 协议数据封装的过程
    以传输层采用TCP或者UPD、网络层采用IP、链路层采用Ethernet为例,可以看到TCP/IP中报文的封装过程如图所示。用户数据经过应用层协议封装后传递给传输层,传输层封装TCP头部,交给网络层,网络层封装IP头部后,再交给数据链路层,数据链路层封装Ethernet帧头和帧尾,交给物理层,物理层以比特流的形式将数据发送到物理线路上。

    不同的协议层对数据包有不同的称谓,在传输层叫做段(segment),在网络层叫做数据报(datagram),在链路层叫做帧(frame)。数据封装成帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部,最后将应用层数据交给应用程序处理。

    目的主机收到数据包后,如何经过各层协议栈最后到达应用程序呢?整个过程如下图所示。

           以太网驱动程序(网卡)首先根据以太网首部中的“上层协议”字段确定该数据帧的有效载荷(payload,指除去协议首部之外实际传输的数据)是IP、ARP还是RARP协议的数据报,然后交给相应的协议处理。假如是IP数据报,IP协议再根据IP首部中的“上层协议”字段确定该数据报的有效载荷是TCP、UDP、ICMP还是IGMP,然后交给相应的协议处理。假如是TCP段或UDP段,TCP或UDP协议再根据TCP首部或UDP首部的“端口号”字段确定应该将应用层数据交给哪个用户进程。IP地址是标识网络中不同主机的地址,而端口号就是同一台主机上标识不同进程的地址,IP地址和端口号合起来标识网络中唯一的进程。

           注意,虽然IP、ARP和RARP数据报都需要以太网驱动程序来封装成帧,但是从功能上划分,ARP和RARP属于链路层,IP属于网络层。虽然ICMP、IGMP、TCP、UDP的数据都需要IP协议来封装成数据报,但是从功能上划分,ICMP、IGMP与IP同属于网络层,TCP和UDP属于传输层。

    2.TCP/IP 数据包
    我们通过 Wireshark 抓包:就分别看到五层数据:

    第一行Frame 3339:物理层数据帧:线路83字节,实际捕获83字节

    第二行Ethernet II:链路层网卡,以太网协议版本II,源地址:厂名_序号(网卡地址),目的:厂名_序号(网卡地址)

    第三行Internet Protocol Version 4:网络层ip数据包,IPV4,源IP地址:10.44.13.7;目的IP是:10.171.8.154

    第四行Transmission Control Protocol:传输层TCP数据包:源端口21000,目的端口:52529;Seq序列号:每发送一个RTP数据包,序列 号就加1;ACK是TCP数据包首部中的确认标志,对已接收到的TCP报文进行确认,其为  183589表示确认号有效;Len长度是17字节;

    第五行data:数据

    整个数据封装的格式如下图所示:

            

    Wireshark显示的下面这些数据信息的顺序与各数据包内各字段的顺序相同,其他帧的内容展开与此类似。

    帧号 时间    源地址          目的地址      高层协议 包内信息概况
    No. Time    Source         Destination      Protocol    Info
    1 0.000000 202.203.44.225   202.203.208.32 TCP     2764 > http [SYN] Seq=0 Len=0 MSS=1460                       源端口>目的端口[请求建立TCP链接]
                               第一层物理层的数据帧概况

    Frame 1 (62 bytes on wire, 62 bytes captured) 1号帧,线路62字节,实际捕获62字节
         Arrival Time: Jan 21, 2008 15:17:33.910261000     捕获日期和时间
         [Time delta from previous packet:0.00000 seconds]此包与前一包的时间间隔
         [Time since reference or first frame: 0.00 seconds]此包与第1帧的间隔时间
         Frame Number: 1                                    帧序号
         Packet Length: 62 bytes                            帧长度
         Capture Length: 62 bytes                           捕获长度
         [Frame is marked: False]                           此帧是否做了标记:否
         [Protocols in frame: eth:ip:tcp]                   帧内封装的协议层次结构
         [Coloring Rule Name: HTTP]            用不同颜色染色标记的协议名称:HTTP
         [Coloring Rule String: http || tcp.port == 80]     染色显示规则的字符串:

                        第二层数据链路层以太网帧头部信息

    Ethernet II, Src: AcerTech_5b:d4:61 (00:00:e2:5b:d4:61), Dst: Jetcell_e5:1d:0a (00:d0:2b:e5:1d:0a)
    以太网协议版本II,源地址:厂名_序号(网卡地址),目的:厂名_序号(网卡地址)
        Destination: Jetcell_e5:1d:0a (00:d0:2b:e5:1d:0a) 目的:厂名_序号(网卡地址)
        Source: AcerTech_5b:d4:61 (00:00:e2:5b:d4:61) 源:厂名_序号(网卡地址)
        Type: IP (0x0800) 帧内封装的上层协议类型为IP(十六进制码0800)看教材70页图3.2

                              第三层网层IP包头部信息

    Internet Protocol, Src: 202.203.44.225 (202.203.44.225), Dst: 202.203.208.32 (202.203.208.32)    互联网协议,源IP地址,目的IP地址
         Version: 4 互联网协议IPv4(此部分参看教材119页图4.15的IPv4数据报字段结构)
         Header length: 20 bytes                             IP包头部长度
         Differentiated Services Field:0x00(DSCP 0x00:Default;ECN:0x00)差分服务字段
         Total Length: 48                                         IP包的总长度

         Identification:0x8360 (33632)                            标志字段

         Flags:       标记字段(在路由传输时,是否允许将此IP包分段,教材125页)

         Fragment offset: 0   分段偏移量(将一个IP包分段后传输时,本段的标识)
         Time to live: 128                                          生存期TTL
         Protocol: TCP (0x06)                         此包内封装的上层协议为TCP
         Header checksum: 0xe4ce [correct]                 头部数据的校验和
         Source: 202.203.44.225 (202.203.44.225)                   源IP地址
         Destination: 202.203.208.32 (202.203.208.32)               目的IP地址

                            以下为传输层TCP数据段头部信息

    Transmission Control Protocol, Src Port: 2764 (2764), Dst Port: http (80), Seq: 0, Len: 0    传输控制协议TCP的内容
         Source port: 2764 (2764)源端口名称(端口号)(此部分参看教材149页图5.7)
         Destination port: http (80)                 目的端口名http(端口号80)
         Sequence number: 0    (relative sequence number)    序列号(相对序列号)
         Header length: 28 bytes                                        头部长度
         Flags: 0x02 (SYN)        TCP标记字段(本字段是SYN,是请求建立TCP连接)
         Window size: 65535                                流量控制的窗口大小
         Checksum: 0xf73b [correct]                         TCP数据段的校验和
         Options: (8 bytes)                                            可选项

    3.TCP 数据包的报文
    1、TCP建立连接,断开,数据传输都是使用同样数据报文格式。

    其中我们抓包看到Transmission Control Protocol 首部的数据信息:

    Transmission Control Protocol, Src Port: 21000, Dst Port:52529, Seq: 12936, ACK 183589 Len: 17    传输控制协议TCP的内容
         Source port: 21000源端口名称(端口号)(用于寻找发端应用进程)
         Destination port: 52529                 目的端口
         Sequence number: 0    (relative sequence number)    序列号(相对序列号,此序列号用来确定传送数据的正确位置,且序列号,用来侦测丢失的包);

        [Next sequence number: 215 (relative sequence number)] #下一个序列号

           Acknowledgement number :183589  是32位确认序号,确认其有效;
         Header length: 32 bytes        头部长度
         Flags: 0x02 (SYN)        TCP标记字段(本字段是SYN,是请求建立TCP连接)
         Window size value: 6364                                流量控制的窗口大小
         Checksum: 0xf73b [correct]                         TCP数据段的校验和
         Options: (12 bytes)                                            可选项

    下面说明详细说明:

     源端口和目的端口:各占2个字节,16比特的端口号加上32比特的IP地址,共同构成相当于传输层服务访问点的地址

      Seq序号:占4个字节,是本报文段所发送的数据部分第一个字节的序号。在TCP传送的数据流中,每一个字节都有一个序号。

             1、假设某时序号为300,简单的理解就是发送方告诉接收端“我发送的数据是从第300开始的”。

             2、假设起数据len=100字节,则下一个报文段的序号就是400;

       ACK 确认序号:占4字节,是期望收到对方下次发送的数据的第一个字节的序号,也就是期望收到的下一个报文段的首部中的序号;

             1、确认序号是上一次已经成功接收到数据字节序号加1。还可以理解为接收端告诉发送端下一次想接收开始序号。假设某时确认序号为1000,简单的理解就是接收方告诉发送方“我已经收到第999序号了,我下一次想接收的数据是从1000开始的”。

             2、由于序号字段有32比特长,可以对4GB的数据进行编号,这样就可保证当序号重复使用时,旧序号的数据早已在网络中消失了;

            在数据传输过程中:

             第一报文发送:Seq1=1  ACK1=1  len1=359

             收到第一个报文回复:Seq2 =1  ACK2=Seq1+ ACK1= 360, len1=17

             下一个报文发送:Seq3=ACK2 =Seq1 (上一个发送的报文seq1 +上一个发送的报文len1)=360    ACK3=Seq1+ ACK1 =18  len3=0

             两次ACK一样:你应该发数据,但我们没有收到数据,所以你还得同样ack继续发送

         

        Header length首部长度(4位):报文头长度(单位:位)/32

        1000(转化为10进制为8,8*32/8 = 32,该报文报头长度为32个字节)

        存在该字段是因为TCP报头中任选字段长度可变

        报头不包含任何任选字段则长度为20字节;4位所能表示的最大值为1111,转化为10进制为15,15*32/8 = 60,故报头最大长度为60字节

       Flag标志位:

                    Nonce Sum:有效排除潜在的ECN滥用,RFC 3540
                    Congestion Window Reduced(CWR):拥塞窗口减少标志
                    ECN-Echo:ECE / ECN标志
                    URG: 紧急指针有效(urgentpointer) 当URG=1时,表明此报文应尽快传送,而不要按原来的排队顺序来传送。与“紧急指针”字段配合使用,紧急指针指出在本报文段中的紧      急数据的最后一个字节的序号,使接收方可以知道紧急数据共有多长;
                    ACK:确认序号有效,只有当ACK=1时,确认序号字段才有意义;
                    PSH:当PSH=1时,表明请求远地TCP将本报文段立即传送给其应用层,而不要等到整个缓存都填满了之后再向上交付。
                    RST:重建连接,当RST=1时,表明出现严重差错,必须释放连接,然后再重建传输连接。复位比特还用来拒绝一个非法的报文段或拒绝打开一个连接;
                    SYN:同步序号用来发起一个连接,在建立连接时使用,当SYN=1而ACK=0时,表明这是一个连接请求报文段。对方若同意建立连接,在发回的报文段中使SYN=1和ACK=1。因此,SYN=1表示这是一个连接请求或连接接受报文,而ACK的值用来区分是哪一种报文;
                    FIN: 发端完成发送任务(主动关闭),用来释放一个连接,当FIN=1时,表明欲发送的字节串已经发完,并要求释放传输连接;

             window窗口大小(2字节):(TCP的流量控制由连接的每一端通过声明的窗口大小来提供。窗口大小为字节数,起始于确认序 号字段指明的值,这个值是接收端正期望接收的字节。窗口大小是一个16bit字段,因而窗口大小最大为65535字节)。

             Checksum检验和(2字节):检验和覆盖整个TCP报文段;强制字段,由发送端计算存储,由接收端进行验证

             Urgent pointer 紧急指针(2字节):当Urgent标志置1时,紧急指针才有效

            Options选项 :选项字段允许每台主机设定能够接受的最大TCP载荷能力(缺省536字节) 。 

            

          

    4.TCP数据报文的Options
     当前,TCP常用的Option如下所示:

    Kind

    (Type)

    Length

    Name

    Reference

    描述 & 用途

    0

    1

    EOL

    RFC 793

    选项列表结束

    1

    1

    NOP

    RFC 793

    无操作(用于补位填充)

    2

    4

    MSS

    RFC 793

    最大Segment长度

    3

    3

    WSOPT

    RFC 1323

    窗口扩大系数(Window Scaling Factor)

    4

    2

    SACK-Premitted

    RFC 2018

    表明支持SACK

    5

    可变

    SACK

    RFC 2018

    SACK Block(收到乱序数据)

    8

    10

    TSPOT

    RFC 1323

    Timestamps

    19

    18

    TCP-MD5

    RFC 2385

    MD5认证

    28

    4

    UTO

    RFC 5482

    User Timeout(超过一定闲置时间后拆除连接)

    29

    可变

    TCP-AO

    RFC 5925

    认证(可选用各种算法)

    253/254

    可变

    Experimental

    RFC 4727

    保留,用于科研实验

     
    一般Option的格式为TLV结构,如下所示:

    Kind / Type(1 Byte)

    Length(1 Byte)

    Value


    1.    EOL和NOP Option(Kind 0、Kind 1)只占1 Byte,没有Length和Value字段;

    2.    NOP用于 将TCP Header的长度补齐至32bit的倍数(由于Header Length字段以32bit为单位,因此TCP Header的长度一定是32bit的倍数);

    3.    SACK-Premitted Option占2 Byte,没有Value字段;

    4.    其余Option都以1 Byte的“Kind”开头,指明Option的类型;Length指明Option的总长度(包括Kind和Length)

    5.    对于收到“不能理解”的Option,TCP会无视掉,并不影响该TCP Segment的其它内容;

     ① .Maximum Segment Size (MSS) Option

     
        一般情况下,通信双方在建立连接时,SYN Segment中会携带MSS Option,MSS指明本端可以接受的最大长度的TCP Segment(Payload,不含TCP Header),也就是说,对端发送数据的长度不应该大于MSS(单位Byte)。
    ————
    1.    首先要明确一点,MSS并非和对端协商的值,而是对对端发送数据长度的“限制”,表明在整个TCP连接期间,都不会接收长度大于MSS的TCP Segment。

    2.    如果收到的SYN中没有MSS,将使用默认值536。MSS Option的Value字段长度固定为16bit,所以MSS最大值为65535(单位Byte)。因此,网络中所有设备都被要求,必须能够处理大小小于576Byte的数据包(IP Header + TCP Header + Default MSS 最小值为 576 Byte)

    3.    IPv4网络中,MSS的典型取值为1460 ,1460Byte + 20Byte IP Header + 20Byte TCP Header = 1500Byte = 以太网典型MTU;

    4.    IPv6网络中,典型MSS取值为1440;另外,如果MSS=65535,表示MSS = PMTU - 60

    ② .Selective Acknowledgment (SACK) Options

     
         在标准的TCP实现中,使用的是累加式的ACK,例如“ACK Num = n”代表对序列号n以前的Bytes进行确认。但是,显然,这样将无法对不连续的Segment进行确认。此外,当出现不连续Segment时,还会导致TCP的接收队列出现一个“坑”,不将这个坑填上,坑后的数据就无法交付给应用程序。

          为解决上述问题,TCP定义了SACK Option,可以使TCP接收者将这个“坑”的位置通告给发送者,让其对这一段数据进行重传。


         注意:若要使用SACK特性,必须在建立连接时,在SYN Segment中附加上SACK-Permitted Option,以此告知对方自己支持SACK。

    SACK-Permitted Option格式如下所示:

    Kind = 4

    Length = 2


    SACK Option通过“Left Edge ~ Right Edge”,指定了一个或多个范围的Seq Num,称为SACK Block,指明了处于“坑”后面(或坑之间)的、已成功接收的Bytes。SACK Option格式如下所示
    ————

    Kind

    (5)

    Length

    (可变)

    Left Edge of 1st Block

    (32bit)

    Right Edge of 1st Block

    (32bit)

    ……

    ……

    Left Edge of nst Block

    (n≤4)

    Right Edge of nst Block

    (n≤4)


    另外,由于TCP Header最长为60 Byte,因此SACK Option中最多只能包含4个SACK Block

    Example(终端A - 终端B)
    ————
    1.    终端A收到了TCP数据流中的Seq Num为0 ~ 1452、2905~4096的字节,但缺少了1453~2904;

    2.    终端A向B发送ACK Segment,其中ACK Num=1453、SACK Option=2905~4097,表明它已经收到了数据流中的Seq Num为2905 ~ 4096的字节,但没有还没收到1453~2904;

    3.    终端B收到这个SACK后,重传包含Byte 1453~2904的TCP Segment;

    4.    终端A向B发送ACK Segment,其中ACK Num=4097,表明它已经收到Seq Num 4097之前的所有字节;

    5.    之后,数据通信恢复正常。


    ③ .Window Scale (WSCALE or WSopt) Option

    TCP Header的Window Size字段长度为16bit,因而正常情况下,Window Advertisement最大只能是65535 Bytes;

    Window Scale Option用于将TCP Header的Window Size字段从16bit扩展至最多30bit,格式如下所示:

    Kind

    (3)

    Length

    (3)

    shift.cnt

    (范围0~14)


    ————
    1.    shift.cnt的取值范围为0~14,表示将Window Advertisement的值扩展至“WindowSize × 2s

    2.    WSopt只能出现在SYN Segment或SYN+ACK Segment中,因此shift.cnt在三次握手之后就会固定下来。

    3.    另外,WSopt是双向独立的,因此连接的两个方向可以有不同的Shift.cnt。但是,WSopt必须双向同时启用,也就是说,如果SYN中不带有WSopt,SYN+ACK中也不能出现WSopt;同样,如果SYN+ACK中不带有WSopt,那么发起SYN的一端就会当作自己也不曾发送过WSopt。

    4.    shift.cnt根据接收Buffer的大小,由TCP自动选取。接收Buffer由系统或程序设定。

     ④ .Timestamps Option and PAWS(Protection against Wrapped Sequence Numbers,防止序列号回绕)

     
    启用Timestamp Option后,每个TCP Segment中都会带有Timestamp Option,其中包含了两个32bit的Timestamp(TSval和TSecr),具体格式如下所示:

    Kind

    (8)

    Length

    (10)

    Timestamp Value(TSval)

    Timestamp Echo Reply(TSecr)


    1.    TSval指明了发送端在发送TCP Segment时的Timestamp;接收端在对该TCP Segment做ACK时,将TSval值回显在TSecr字段中。

    注意:由于TCP连接是双向的,接收端在ACK中回显TSecr时,也会把自己当前的Timestamp放入TSval字段。

    2.    Timestamp是一个随时间单调递增的值,由于TCP接收端只需要在ACK中将TSval简单地回显,因此通信双方并不需要进行时间同步等操作。

    3.    通过Timestamp Option,发送端再也不需要在内存中保存发送Segment的时间了,只需要将其放入TSval,然后接收端将其回显在ACK Segment即可。当发送端收到ACK Segment后,取出TSscr,和当前时间做算术差,即可完成一次RTT的测量。

    4.    若非通过Timestamp Option来计算RTT,大部分TCP实现只会以“每个Window采样一次”的频率来测算RTT。因此通过Timestamp Option,可以实现更密集的RTT采样,使RTT的测算更精确。

    另外,Timestamp Option还有PAWS(Protection Against Wrapped Sequence Numbers,防止序列号回绕)功能,详见以下示例
    ————
    1.    假设TCP Window Size为1GB(使用Window Scale),发送者每发送一个Window的数据Timestamp值加100,数据的发送情况如下所示:

    时间点

    发送数据量

    Seq Num

    Timestamp

    接收

    1

    0G:1G

    0G:1G

    0~100

    OK

    2

    1G:2G

    1G:2G

    100~200

    其中某些Segment丢包后重传

    3

    2G:3G

    2G:3G

    200~300

    OK

    4

    3G:4G

    3G:4G

    300~400

    OK

    5

    4G:5G

    0G:1G

    400~500

    OK

    6

    5G:6G

    1G:2G

    500~600

    此前丢包的Segment出现了

    2.    在时间点2的时候,发生了丢包;在时间点4和5之间,序列号发生了回绕;在时间点6,已经被认为“丢包”的Segment延迟到达了。

    3.    由于延时到达的Segment的timestamp为1xx,小于时间点6的有效timestamp(5xx),因此这个Segment会根据PAWS机制丢弃,从而不会对TCP造成影响。

    使用TCP Timestamps option (TSopt) 进行RTT采样。当前大部分操作系统(Linux、Windows)的实现方式如下

     User Timeout (UTO) Option

    UserTimeout值表明了TCP发送者等待ACK的时间,如果在指定时间内没收到ACK,就会认为对端挂掉。对于传统TCP(RFC 793)而言,UserTimeout是本地配置的。RFC 1122建议,当TCP重传3次后,应该通知应用程序,100s后,应该拆除连接。

    通过UTO,可以让TCP将UserTimeout值“告知”给对端,UTO格式如下所示:

    Kind

    (28)

    Length

    (4)

    G bit(Granularity bit)

    UserTimeout


    1.    G bit = 1,表示UserTimeout的单位为分钟;G bit = 0,表示UserTimeout的单位为秒

    2.    通过UTO,TCP接收者可以根据“对端的UserTimeout”来调整自己的行为。UserTimeout建议取值为:min(U_Limit,max(Adv_UTO,Remot_UTO,L_Limit))

    o U_Limit是本地UserTimeout的最高限制;Adv_UTO是通告出去的UserTimeout;Remot_UTO是对端的UserTimeout;L_Limit是本地UserTimeout的最低限制;

    3.    要注意的是,UTO只是用于“告知”,TCP接收者却不一定要根据对端的UTO值来调整自己的行为。

    4.    此外,NAT设备也可以根据UTO来调整连接保活计时器

    5.    若使用 = min(U_LIMIT, max(ADV_UTO, REMOTE_UTO, L_LIMIT))

    ⑥ .Authentication Option (TCP-AO)and TCP MD5 Signature Option(TCP-MD5)

     
    TCP-MD5和TCP-AO主要用于防止TCP欺骗攻击(TCP Spoofing Attacks)。TCP-MD5是旧标准(RFC 2385),例如BGP、LDP等协议就是以TCP-MD5作为认证手段的。2010年后,IETF建议使用TCP-AO去取代TCP-MD5,然而TCP-AO当前的普及率还很低。

    TCP-MD5和TCP-AO的格式如下所示
    ————

    TCP-MD5 Option的MD5 Hash根据以下信息计算:

    1.TCP伪头部
    2.TCP头部(包括Option,checksum设为0)
    3.TCP Segment Data
    4.密钥

    相对于TCP-MD5,TCP-AO的主要改进之处在于:
    1.    支持多种MAC算法

    2.    支持带内的密钥变更操作

    注意:TCP-AO与TCP-MD5一样,都不包含密钥分发机制。因此在密钥分发方面都存在一定风险
    ---------------------
    作者:规速
    来源:CSDN
    原文:https://blog.csdn.net/hguisu/article/details/12521597
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    arguments.callee
    vue的生命周期
    Vue中的v-cloak用法
    控制input只能输入数字和两位小数
    css3新单位vw、vh的使用详解
    关于图片的Base64编码
    Logic and Fault simulation
    scan design flow(二)
    scan design flow(一)
    异构计算
  • 原文地址:https://www.cnblogs.com/lanjianhappy/p/9861531.html
Copyright © 2011-2022 走看看