4. TCP的连接和关闭过程

4.1 TCP连接的三次握手和四次挥手

(1)三次握手

  ①第1次握手:建立连接。客户端发送连接请求报文段(SYN=1,sequence Number=x);然后客户端进入SYN_SEND状态,等待服务器确认

  ②第2次握手:服务器收到SYN报文段,然后对SYN报文段进行确认,并设置(Acknowlegement Number为x+1)。同时,自己还要发送SYN请求信息。上述信息放到一个报文段(SYN+ACK)中,一并发送给客户端,此时服务器进入SYN_RECV状态

  ③第3次握手:客户端收到服务器的SYN+ACK报文段。然后将ACK设置为y+1,向服务器发送ACK报文,这个报文段发送完以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP的三次握手。

(2)四次挥手

  ①第1次挥手客户端(也可以是服务端)设置seq和ACK,向服务器发送一个FIN报文段。此时,客户端进入FIN_WAIT_1状态,表示客户端没有数据要发送给服务器了

  ②第2次挥手服务器收到客户端发送的FIN报文段,向客户端回一个ACK报文,客户端收到后进入FIN_WAIT_2状态;表示服务端收到客户端的关闭请求,但服务端可能还有数据没发完,让客户端继续等服务端的通知

  ③第3次挥手服务器向客户端发送FIN报文,表示服务端数据己发送完毕,可以关闭连接。同时服务器进入LAST_ACK状态

  ④第4次挥手客户端收到服务器发送的FIN报文,向服务器发送ACK报文,然后客户端进入TIME_WAIT状态。服务器收到客户端的ACK报文段后,就关闭连接。此时,客户端等待2MSL后就关闭连接了。

4.2 为什么要三次握手

(1)可防止己失效的连接请求报文突然又传递到服务端

  ①假设Client发出第1个连接请求报文段并没有丢失而是在某个网络结点长时间滞留,以致延误到以后的某个时间才到达Server。但这时客户端己经因超时重发一个连接请求报文段给Server,并正常建立了连接。

  ②如果采用两次握手那么当这个延迟的连接请求到达时,服务端只需发送一个确认,新的连接就会在服务端建立起来。但客户端收到这个确认,它会认为自己并没有发出请求(因为该请求己失效!),因此就不会理会服务端的确认,也不会向服务端发送数据而服务端则认为新的连接己经建立了,就一直等待客户端发送数据,直到超出保活计时器设置值才判断客户端出了问题,这样无形中就会浪费服务器的资源

  ③而如果采用3次握手,服务端收到延迟的连接请求(第1次握手)并向客户端发送确认,但客户端收到这个确认时(第2次握手),同样并不会理会它,因此也就不会与服务端进行第3次握手。由于采用三次握手机制,这时服务端因没握过第3次手,所以并不会建立连接这样就可以解决失效请求突然到达的问题

(2)可靠性的理解

  ①世界上不存在完全可靠的通信协议。当A发送一个请求给B时,为了保证可靠性,B需要给A发一个己收到请求的确认包,但B的这个确认包是否到达A,需要A发送一个确认的确认给B,而这个确认B是否收到,仍需要B发给A一个确认,如此无休止去确认下去…。因此,从理论上无法做到完全的可靠,一般只需3次握手即可保证有较高的可靠性。

  ②“三次握手”是点对点通信的一般规则,但即使三次握手成功,也只能说明之前的通信条件和环境,而不能决定和预测之后的通信环境。根据经验,两个端点通信失败,最大的可能性是端点本身的故障,而三次握手成功排除了这种可能(见后面4.4中对讲机的例子)。以后的情况很难预测。通信协议只能做到尽可能的可靠,而不能做到理论上的完全可靠

  ③由于TCP是面向连接的,无论哪一方向另一方发送数据,都必须在双方之间建立一个可靠的连接。

4.3 为什么需要4次挥手

(1)发起中断连接可以是客户端也可以是服务端。假设这里由客户端发起。当发送FIN报文时表示“我(Client)没有数据要发给你了”但如果你有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据

(2)服务端收到客户端的FIN报文后,先发送一个ACK,用于告诉客户端“你的请求我收到了,但我还没准备好,请你继续等我的消息”。这时客户端进入FIN_WAIT_1状态,继续等待Server端的FIN报文。

(3)当服务端确定数据己发送完毕,则向Client端发送FIN报文告诉Client端,好了,我(Server)这边的数据己发送完结了,准备好关闭连接了

(4)客户端收到服务端的FIN报文后,就知道可以关闭连接了。但服务端并不知道客户端收到这个FIN报文没有,因此客户端要发送最后一个ACK报文,以便告知服务器己收到FIN,如果服务器收到这个ACK,就可以关闭连接。但现在客户端并不急着马上关闭连接,因为最后一个ACK可能丢失,所以客户端要等2MSL(2倍的最大报文生存时间)的时间,如果这期间没有收到服务器的信息,说明服务器己经关闭,否则需重发最后的那个ACK报文。

4.4 生活中的例子

(1)对讲机的三次握手

  ①C→S:“喂,你听得到吗?”(C ->SYN_SEND)

  ②S→C:“听到,你听得到我吗?”(应答与请求同时发出,S->SYN_RCVD | C ->ESTABLISHED。注意:第2次握手,能说明C的发和S的收都没问题)。

  ③C→S:“能听到,今天balabala……”(S->ESTABLISHED。注意:第3次握手能说明C的收和S的发也没问题。到此TCP的双工模式被证明能正常工作!)

(2)四次挥手

  ①C→S:“喂,我不说了。”(C→FIN_WAIT1)

  ②S→C:“我知道了。等下,上一句还没说完。Balabala…..”(S→CLOSE_WAIT && C→FIN_WAIT2)

  ③S→C:好了,说完了,我也不说了。”(S→LAST_ACK)

  ④C→S:我知道了。” S关闭连接,C等待S收到了消息(时长:2MSL),如果这段时间S无回应,说明S己关闭。否则重说一次”我知道了”给S端。(C→TIME_WAIT && S→CLOSED,最后C→CLOSED)

第13章 TCP编程(2)_TCP的连接和关闭过程的更多相关文章

  1. 第13章 TCP编程(1)_socket套接字

    1. socket套接字 (1)套接字简介 ①socket是一种通讯机制,它包含一整套的调用接口和数据结构的定义,它给应用进程提供了使用如TCP/UDP等网络协议进行网络通讯的手段. ②Linux中的 ...

  2. 第13章 TCP编程(4)_基于自定义协议的多线程模型

    7. 基于自定义协议的多线程模型 (1)服务端编程 ①主线程负责调用accept与客户端连接 ②当接受客户端连接后,创建子线程来服务客户端,以处理多客户端的并发访问. ③服务端接到的客户端信息后,回显 ...

  3. 第13章 TCP编程(3)_基于自定义协议的多进程模型

    5. 自定义协议编程 (1)自定义协议:MSG //自定义的协议(TLV:Type length Value) typedef struct{ //协议头部 ];//TLV中的T unsigned i ...

  4. 五十五、linux 编程——TCP 连接和关闭过程及服务器的并发处理

    55.1 TCP 连接和关闭过程 55.1.1 介绍 建立连接的过程就是三次握手的过程:客户端发送 SYN 报文给服务器,服务器回复 SYN+ACK 报文,客户机再发送 ACK 报文. 关闭连接的过程 ...

  5. TCP/IP协议的建立连接与关闭连接过程

    一.建立连接(三次握手) 第一次握手:建立连接时,客户端发送SYN(seq=x)包到服务器,并进入SYN_SENT状态,等待服务器的确认.SYN:同步序列编号(Synchronize Sequence ...

  6. 【RL-TCPnet网络教程】第13章 RL-TCPnet之TCP服务器

    第13章      RL-TCPnet之TCP服务器 本章节为大家讲解RL-TCPnet的TCP服务器实现,学习本章节前,务必要优先学习第12章TCP传输控制协议基础知识.有了这些基础知识之后,再搞本 ...

  7. 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化

    第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...

  8. UNIX网络编程 第5章 TCP客户/服务器程序示例

    UNIX网络编程 第5章 TCP客户/服务器程序示例

  9. 《Clojure编程》笔记 第13章 测试

    目录 背景简述 第13章 测试 13.1 术语 13.2 clojure.test 13.2.1 定义测试的两种方式 13.2.1.1 用deftest宏把测试定义成单独的函数 13.2.1.2 用w ...

随机推荐

  1. UIViewController之间的相互跳转

    一.最普通的视图控制器UIViewContoller 一个普通的视图控制器一般只有模态跳转的功能(ipad我不了解除外,这里只说iPhone),这个方法是所有视图控制器对象都可以用的,而实现这种功能, ...

  2. 26个你不知道的Python技巧

    Python是目前世界上最流行的编程语言之一.因为: 1.它容易学习 2.它用途超广 3.它有非常多的开源支持(大量的模块和库) 不好意思,优达菌又啰嗦了. 本文作者 Peter Gleeson 是一 ...

  3. apache的日志access_log分析

    正常日志格式:客户端地址 访问者的标识 访问者的验证名字 请求的时间 请求类型 请求的HTTP代码 发送给客户端的字节数   当网站出问题时分析日志,第一步一般都不会是看访问日志.但是也不能忽视它,在 ...

  4. xxx/labelKeypoint/utils/qt.py:81: RuntimeWarning: invalid value encountered in double_scalars

    原代码: return np.linalg.norm(np.cross(p2 - p1, p1 - p3)) / np.linalg.norm(p2 - p1) 出现报错: xxx/labelKeyp ...

  5. screen 命令 http://man.linuxde.net/screen

    http://man.linuxde.net/screen -A 将所有的视窗都调整为目前终端机的大小. -d <作业名称> 将指定的screen作业离线. -h <行数> 指 ...

  6. SWIFT中数字格式

    SWIFT中格式化数字比较常用的应该就是以下几种格式了. var formatter = NSNumberFormatter() //formatter.numberStyle = NSNumberF ...

  7. C语言基础:常见循环语句 分类: iOS学习 c语言基础 2015-06-10 21:46 13人阅读 评论(0) 收藏

    for语句 for( 初始化表达式; 循环判断条件  ;增量表达式); while(条件表达式){ 循环体; } 先判断条件表达式,如果为真就执行循环体,执行完再去判断条件表达式 do{ 循环体; } ...

  8. tensorflow模型持久化保存和加载

    模型文件的保存 tensorflow将模型保持到本地会生成4个文件: meta文件:保存了网络的图结构,包含变量.op.集合等信息 ckpt文件: 二进制文件,保存了网络中所有权重.偏置等变量数值,分 ...

  9. php-fpm配置及操作

    启动与停止 启动 /usr/local/php/sbin/php-fpm 停止 pkill php-fpm

  10. DataFrame 列运算

    import pandas as pd import StringIO table_buffer = StringIO.StringIO('''a b 2007-01-08 0.786667 270 ...