第13章 TCP编程(2)_TCP的连接和关闭过程
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的连接和关闭过程的更多相关文章
- 第13章 TCP编程(1)_socket套接字
1. socket套接字 (1)套接字简介 ①socket是一种通讯机制,它包含一整套的调用接口和数据结构的定义,它给应用进程提供了使用如TCP/UDP等网络协议进行网络通讯的手段. ②Linux中的 ...
- 第13章 TCP编程(4)_基于自定义协议的多线程模型
7. 基于自定义协议的多线程模型 (1)服务端编程 ①主线程负责调用accept与客户端连接 ②当接受客户端连接后,创建子线程来服务客户端,以处理多客户端的并发访问. ③服务端接到的客户端信息后,回显 ...
- 第13章 TCP编程(3)_基于自定义协议的多进程模型
5. 自定义协议编程 (1)自定义协议:MSG //自定义的协议(TLV:Type length Value) typedef struct{ //协议头部 ];//TLV中的T unsigned i ...
- 五十五、linux 编程——TCP 连接和关闭过程及服务器的并发处理
55.1 TCP 连接和关闭过程 55.1.1 介绍 建立连接的过程就是三次握手的过程:客户端发送 SYN 报文给服务器,服务器回复 SYN+ACK 报文,客户机再发送 ACK 报文. 关闭连接的过程 ...
- TCP/IP协议的建立连接与关闭连接过程
一.建立连接(三次握手) 第一次握手:建立连接时,客户端发送SYN(seq=x)包到服务器,并进入SYN_SENT状态,等待服务器的确认.SYN:同步序列编号(Synchronize Sequence ...
- 【RL-TCPnet网络教程】第13章 RL-TCPnet之TCP服务器
第13章 RL-TCPnet之TCP服务器 本章节为大家讲解RL-TCPnet的TCP服务器实现,学习本章节前,务必要优先学习第12章TCP传输控制协议基础知识.有了这些基础知识之后,再搞本 ...
- 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化
第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...
- UNIX网络编程 第5章 TCP客户/服务器程序示例
UNIX网络编程 第5章 TCP客户/服务器程序示例
- 《Clojure编程》笔记 第13章 测试
目录 背景简述 第13章 测试 13.1 术语 13.2 clojure.test 13.2.1 定义测试的两种方式 13.2.1.1 用deftest宏把测试定义成单独的函数 13.2.1.2 用w ...
随机推荐
- C# 高性能的数组 高性能数组队列实战 HslCommunication的SharpList类详解
本文将使用一个gitHub开源的组件技术来实现这个功能 github地址:https://github.com/dathlin/HslCommunication ...
- iOS 开发 Framework
制作Framework 的好处和缺点 好处: 1.如果模块间接口定义的比较完善,模块化的程序具有很好的可扩展性与内聚性: 2.物理上的模块化便于开发过程的管理与测试,尤其是在程 ...
- ZOJ2402 Lenny's Lucky Lotto List 简单DP
Lenny's Lucky Lotto Lists Time Limit: 2 Seconds Memory Limit:65536 KB Lenny likes to play the g ...
- Uboot启动命令使用
1.查看根文件系统中的内容 打断Uboot的启动,默认从SD卡启动,查看根文件系统中/boot下的内容(根文件系统在mmcblk0p1上):=> mmc rescan=> ext4ls m ...
- grandstack 基于graphql&&react&& apollo&& neo4j 的全栈开发工具
grandstack是一个基于graphql&&react&& apollo&& neo4j 的全栈开发工具. 有篇关于graphql 的5个常见问题的 ...
- Linux性能测试工具安装全集
stress 下载地址:http://people.seas.harvard.edu/~apw/stress/ 一.stress工具安装:1.获取stress源码安装包(stress-1.0.4.ta ...
- xml时间配置
这些星号由左到右按顺序代表 : * * * * * * * 秒 分 时 日 月 周 年 序号 说明 是否必填 允许填写的值 允许的通配符 秒 是 0-59 , - * / 分 是 0-59 , - * ...
- 使用python生成词云
什么是词云呢? 词云就是一些关键词组成的一个图片.大家在网上经常看到,下面看一些例子: 那用python生成一个词云的话怎么办呢,首先要有一些词,咱们随便找个吧,用see you again的歌词好了 ...
- Windows nginx php cgi-fcgi 配置 xdebug
之前使用的是 Apache + PHP,不用怎么配置就可以. 由于服务器用的是 nginx,为了和服务器一致,所以本地开发也改为 nginx. 开始只是简单的开启 xdebug, 发现并不行. 找了一 ...
- POJ2392 Space Elevator
题目:http://poj.org/problem?id=2392 一定要先按高度限制由小到大排序! 不然就相当于指定了一个累加的顺序,在顺序中是不能做到“只放后面的不放前面的”这一点的! 数组是四十 ...