码迷,mamicode.com
首页 > 其他好文 > 详细

TCP 协议 ---- "三次握手,四次挥手"

时间:2016-06-12 16:59:42      阅读:222      评论:0      收藏:0      [点我收藏+]

标签:三次握手   四次挥手   

一、TCP 协议

    1、概念:TCP协议,即 传输控制协议。它是面向连接、可靠的传输层协议。

    2、特点:工作在 传输层;每一条TCP连接只能是点对点的;面向连接、可靠性;提供全双工通信;基于字节流。

    3、TCP 数据报格式:   TCP 基于 字节流

        技术分享

  源端口号、目的端口号:各占 2字节(16位) 序号:4字节 范围[0,2^32 - 1],使用mod/(2^32)计算

  URG:紧急  1 紧急指针字段有效            ACK:确认  1 确认字段有效

  PSH:推送  两应用进行交互,一方希望发送命令后就立即收到对方响应

  RST:复位 (重建位/重置位) 1 TCP连接出现严重错误,须释放连接,再重新建立连接

  SYN:同步  1 连接请求/连接接受报文

  FIN:终止  1 数据已发送完毕,释放连接

  窗口字段:现在允许对方发送的数据量

  检验和:2字节  范围[首部 + 数据]

  紧急指针:2字节 (仅在URG=1时有意义)指出紧急数据的末尾在文段中的位置

  MSS:最大报文长度 [TCP报文长度 - TCP首部长度]

  选项:长度可变(最长40字节) 若无选项,则 TCP首部长度 20字节


    3、连接: 套接字socket = (IP地址 :端口号)



 

            技术分享



I. 三次握手:    建立连接的过程:

    1.客户端发出段1,SYN位表示连接请求。

    序号是1000,这个序号在网络通讯中用作临时的地址,每发一个数据字节,这个序号要加1,这样在接收端可以根据序号排出数据包的正确顺序,也可以发现丢包的情况。另外,规定SYN位和FIN位也要占一个序号,这次虽然没发数据,但是由于发了SYN位,因此下次再发送应该用序号1001。mss表示最大段尺寸,如果一个段太大,封装成帧后超过了链路层的最大帧长度,就必须在IP 层分片,为了避免这种情况,客户端声明自己的最大段尺寸,建议服务器端发来的段不要超过这个长度。 

    2.服务器发出段2,也带有SYN位,同时置ACK位表示确认,确认序号是1001,表示“我接收到序号1000及其以前所有的段,请你下次发送序号为1001的段”,也就是应答了客户端的连接请求,同时也给客户端发出一个连接请求,同时声明最大尺寸为1024。 

    3.客户端发出段3,对服务器的连接请求进行应答,确认序号是8001。


II. 四次握手:   关闭连接的过程:

    1. 客户端发出段7, FIN位:关闭连接的请求。

       2. 服务器发出段8, 应答客户端的关闭连接请求。
       3. 服务器发出段9, 其中也包含FIN位,向客户端发送关闭连接请求。

       4. 客户端发出段10, 应答服务器的关闭连接请求。

注:正在关闭或者TIME_WAIT状态的tcp连接,不能传输http请求和响应。


III.TIME_WAIT

   通信双方建立TCP连接后,主动关闭连接的一方就会进入TIME_WAIT状态。

客户端主动关闭连接时,会发送最后一个ack后,然后会进入TIME_WAIT状态,再停留2个MSL时间(后有MSL的解释),进入CLOSED状态。

    MSL就是maximum segment lifetime(最大分节生命期),这是一个IP数据包能在互联网上生存的最长时间,超过这个时间IP数据包将在网络中消失 。MSL在RFC 1122上建议是2分钟,而源自berkeley的TCP实现传统上使用30秒。

TIME_WAIT状态维持时间: 两个MSL时间长度,也就是在1-4分钟。Windows操作系统就是4分钟。

    

    1)客户端主动关闭连接

[ 进入TIME_WAIT状态的一般情况下是客户端 ]

    大多数服务器端一般执行被动关闭,服务器不会进入TIME_WAIT状态。

    当在服务器端关闭某个服务再重新启动时,服务器是会进入TIME_WAIT状态的。

举例:

1.客户端连接服务器的80服务,这时客户端会启用一个本地的端口访问服务器的80,访问完成后关闭此连接,立刻再次访问服务器的

80,这时客户端会启用另一个本地的端口,而不是刚才使用的那个本地端口。原因就是刚才的那个连接还处于TIME_WAIT状态。

2.客户端连接服务器的80服务,这时服务器关闭80端口,立即再次重启80端口的服务,这时可能不会成功启动,原因也是服务器的连接还处于TIME_WAIT状态。

 

服务端提供服务时,一般监听一个端口就够了。例如Apach监听80端口。

客户端则是使用一个本地的空闲端口(大于1024),与服务端的Apache的80端口建立连接。

当通信时使用短连接,并由客户端主动关闭连接时,主动关闭连接的客户端会产生TIME_WAIT状态的连接,一个TIME_WAIT状态的连接就占用了一个本地端口。这样在TIME_WAIT状态结束之前,本地最多就能承受6万个TIME_WAIT状态的连接,就无端口可用了。

客户端与服务端进行短连接的TCP通信,如果在同一台机器上进行压力测试模拟上万的客户请求,并且循环与服务端进行短连接通信,那么这台机器将产生4000个左右的TIME_WAIT socket,后续的短连接就会产生address already in use : connect的异常。

 

关闭的时候使用RST的方式,不进入 TIME_WAIT状态,是否可行?

 

    2)服务端主动关闭连接

    [ 大多数服务器端一般执行被动关闭,服务器不会进入TIME_WAIT状态 ]

    服务端提供在服务时,一般监听一个端口就够了。例如Apach监听80端口。

    客户端则是使用一个本地的空闲端口(大于1024),与服务端的Apache的80端口建立连接。

    当通信时使用短连接,并由服务端主动关闭连接时,主动关闭连接的服务端会产生TIME_WAIT状态的连接。

    由于都连接到服务端80端口,服务端的TIME_WAIT状态的连接会有很多个。 

服务器端为了解决这个TIME_WAIT问题,可选择的方式有三种:

     保证由客户端主动发起关闭(即做为B端)

     关闭的时候使用RST的方式

     对处于TIME_WAIT状态的TCP允许重用

 3)使用情形    

    技术分享


返回结果如下:

    LAST_ACK 14

    SYN_RECV 348

    ESTABLISHED 70

    FIN_WAIT1 229

    FIN_WAIT2 30

    CLOSING 33

    TIME_WAIT 18122

 

对上述结果的解释:

    CLOSED:无连接是活动的或正在进行

    LISTEN:服务器在等待进入呼叫

    SYN_RECV:一个连接请求已经到达,等待确认

    SYN_SENT:应用已经开始,打开一个连接

    ESTABLISHED:正常数据传输状态

    FIN_WAIT1:应用说它已经完成

    FIN_WAIT2:另一边已同意释放

    ITMED_WAIT:等待所有分组死掉

    CLOSING:两边同时尝试关闭

    TIME_WAIT:另一边已初始化一个释放

    LAST_ACK:等待所有分组死掉


本文出自 “花开彼岸” 博客,请务必保留此出处http://zxtong.blog.51cto.com/10697148/1788267

TCP 协议 ---- "三次握手,四次挥手"

标签:三次握手   四次挥手   

原文地址:http://zxtong.blog.51cto.com/10697148/1788267

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!