zoukankan      html  css  js  c++  java
  • 三次握手和四次挥手

    前文

    因为三次握手和四次挥手必须设计到报文的发送与接收,下面说明下TCP报文

    1、TCP报文结构

    TCP报文段也分为首部数据两部分,首先默认情况下一般是20字节的长度(图中显示每段或者说每层是0-31bit,即每层长度时32,字节和比特的换算公式应该是1字节=8比特),但是在一些特殊情况下,会使用“可选字段”,这时,首部长度会有所增加。

    #源端口随机分配,目标端口使用知名端口。由于TCP协议头部使用16位来保存端口号,所以端口的个数大于65536个,即2^16=65536
    #应用客户端使用的源端口一般为系统中未使用的且大于1023的。
    #目的端口号为服务器端应用服务的进程,如telnet为23.

    2、TCP控制字段说明介绍

    【紧急字段URG】--1bit
    当URG=1时,此字段告诉系统此报文中有紧急数据,应尽快传送。
    【确认字段ACK】--1bit   ※※※
    当ACK=1时,表示确认,且确认好有效,当ACK=0时,确认字段无效。
    【推送字段PSH】- 1bit 
     当PSH=1时,则报文段会被尽快地交付给目的方,不会对这样的报文段使用缓存策略。 
    【复位字段RST】- 1bit 
       当RST为1时,表明TCP连接中出现了严重的差错,必须释放连接,然后再重新建立连接。 
    【同步字段SYN】- 1bit ★★★★
      当SYN=1时,表示发起一个连接请求。 
    【终止字段FIN】- 1bit ★★★★
      用来释放连接。当FIN=1时,表明此报文段的发送端的数据已发送完成,并要求释放连接。

    3、TCP报文字段详细说明

    1.【源端口】 ---字段说明(占用16bit,即2个字节),表示网络访问来源处的端口号,即指定了发送端的端口。
    2.【目的端口】---字段说明(占用16bit,即2个字节):表示网络访问目的处的端口号,即指定了接受段的端口号。
    说明:由上面可以看出,源端口和目标端口都是占用了16bit/2字节,因此也可以通过计算得知源目标端口范围是2的16次方=65536
    3.【序列号】---字段说明(占用32bit,即4字节):每一个TCP报文段都会有一个序号,序号字段的值其实是本报文段所发送的数据的第一个字节的序号。
    这是因为TCP是面向连接的可靠服务,其每一个字节都会对应一个序号,通过序号来确保服务的可靠性和有序性。标识数据包传输的顺序,便于数据包拆分后,进行重新组装
    4.【确认号】---字段说明(占用32bit,即4字节),确认号是期望收到对方的下一个报文段的数据的第一个字节的序号。
    简单理解就是发送端发送一个seq序列号x,接收端需要回复一个确认号x+1;并发送一个序列号Y,发送端接收一个seq序列号Y,接收端需要回复一个确认号y+1 5.【数据偏移】---字段说明(占用4bit):其实他本质上就是“首部长度”,因为“数据偏移”是指TCP报文段的数据部分的起始处距离TCP报文段的起始处的距离,
    数据偏移总共占用4bit,因此最大能表示的数值为15,而数据偏移的单位是“4字节”。

    位概念:根据TCP包头字段,存在三个重要的标识ACK SYN FIN

    ACK:数字为1表示确认收到发送请求,表示确认

    SYN :位数字为1表达式建立TCP连接

    FIN:数字1表示断开TCP连接

    TCP三次握手

    1、TCP三次握手建立过程简单说明

     

    1)由主机A发送建立TCP连接的请求报文,其中报文中包含seq序列号,是由发送端随机生成的,并且还将报文中SYN字段置位1,表示需要建立TCP连接请求。
    2)主机B会回复A 发送的TCP连接请求报文,其中包含seq序列号,也是由回复段随机生成的,并且将回复报文的SYN字段置1,而且会产生ACK验证字段,
    ack验证字段数值是在A发过来的seq序列号基础上加1进行回复;并且还会回复ACK确认控制字段,以便A收到信息时,知晓自己的TCP建立请求已得到确认。
    3)A端收到B端发送的TCP建立请求后,会使自己的原有序列号加1进行再次发送序列号,并且再次回复ACK验证请求,在B段发送过来的seq基础上加1进行回复;
    同时也会回复ack确认控制字段以便B收到信息时,知晓自己的TCP建立请求已经得到了确认。

    2、TCP三次握手状态转换说明:

    首先,建立连接之前的服务器和客户端的状态都为CLOSED.
    服务器创建socket后开始监听,变为LISTEN状态。
    客户端请求建立连接,向服务器发送SYN报文,客户端的状态变为SYN_SENT.
    服务端收到客户端的报文后向客户端发送ACK和SYN报文,此时服务器的状态变为SYN_RCVD.
    然后,客户端收到ACK,SYN,就向服务器发送ACK,客户端状态变为ESTABLISHED.
    服务器收到客户端的ACK后也变为ESTABLISHED.
    此时3次握手完成,连接建立。

    3、11种状态集转换

    TCP四次挥手

    由于tcp连接时全双工的,断开连接会比建立连接麻烦点。
    客户端先向服务器发送FIN报文,请求断开连接,其状态变为FIN_WAIT1.
    服务端收到FIN后向客户端发送ACK,服务器状态变为CLOSE_AWIT.
    客户端收到ACK后就进入FIN_WAIT2的状态,此时连接已经断开了一半,如果服务器还有数据要发送给客户端,就会继续发送。
    直到发送完了,就发送FIN报文,此时服务器就进入LAST_ACK状态。
    客户端收到服务器的FIN后,马上发送ACK给服务器,此时客户端进入TIME_WAIT状态,再过了2MSL时间后进入CLOSED状态,服务器收到客户端的ACK就进入CLOSED状态。

    名词解释:

    1.MSL介绍
    主动关闭的Socket端会进入TIME_WAIT状态,并且持续2MSL时间长度,MSL就是maximum segment lifetime
    (最大分节生命期),这是一个IP数据包能在互联网上生存的最长时间,超过这个时间将在网络中消失。
    MSL在RFC 1122上建议是2分钟,而源自berkeley的TCP实现传统上使用30秒,因而,TIME_WAIT状态一般维持在1-4分钟。
    
    2. time_wait状态作用说明
    TIME_WAIT状态存在的理由:
    1)可靠地实现TCP全双工连接的终止
    在进行关闭连接四路握手协议时,最后的ACK是由主动关闭端发出的,如果这个最终的ACK丢失,服务器将重发最终的FIN,
    因此客户端必须维护状态信息允许它重发最终的ACK。如果不维持这个状态信息,那么客户端将响应RST分节,服务器将此分节解释成一个错误(在java中会抛出connection reset的SocketException)。
    因而,要实现TCP全双工连接的正常终止,必须处理终止序列四个分节中任何一个分节的丢失情况,主动关闭的客户端必须维持状态信息进入TIME_WAIT状态。
     
    2)允许老的重复分节在网络中消逝 
    TCP分节可能由于路由器异常而“迷途”,在迷途期间,TCP发送端可能因确认超时而重发这个分节,迷途的分节在路由器修复后也会被送到最终目的地,这个原来的迷途分节就称为lost duplicate。
    在关闭一个TCP连接后,马上又重新建立起一个相同的IP地址和端口之间的TCP连接,后一个连接被称为前一个连接的化身(incarnation),那么有可能出现这种情况,前一个连接的迷途重复分组在前一个连接终止后出现,从而被误解成从属于新的化身。
    为了避免这个情况,TCP不允许处于TIME_WAIT状态的连接启动一个新的化身,因为TIME_WAIT状态持续2MSL,就可以保证当成功建立一个TCP连接的时候,来自连接先前化身的重复分组已经在网络中消逝。
  • 相关阅读:
    Android实例-Delphi在运行时更改Android屏幕旋转(IOS也支持,不过我可没有苹果机,测试不了)
    delphi实现电脑屏幕旋转(电脑屏幕,不是手机屏幕)
    教程-关于escape和URI之间的不同!
    在Delphi中URLEncode文件名的最佳方法是什么?
    Delphi实现js中的escape()编码和unescape()解码
    面向对象: 接口与对象生存周期,接口自动释放
    问题-Delphi在做窗体派生时提示Resource TForm2 not found
    问题-delphi idTCPserver-Socket error问题详解
    delphi 求两个时间差
    Delphi 解决StrToDateTime()不是有效日期类型的问题
  • 原文地址:https://www.cnblogs.com/dadonggg/p/8581160.html
Copyright © 2011-2022 走看看