TCP传输连接建立与释放详解
一直以来有许多读者朋友对TCP的传输连接建立和释放过程不是很理解,而这又是几乎网络认证中必考的知识点,包括软考、CCNA\CCNP、H3CNA\H3CNE等,为此再把笔者年度巨作,广受好评的——《深入理解计算机网络》书中的相关内容摘出来与大家分享。本书详细内容及读者评价可从这里了解:http://item.jd.com/11165825.html,http://product.dangdang.com/23166396.html(目前7折促销中)
10.3.6 TCP传输连接建立
TCP是一个面向连接的传输层协议,所以无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条传输连接。本节将详细讨论一个TCP传输连接是如何建立的。
1. 单方主动连接的TCP连接建立过程
在TCP/IP协议体系结构中的TCP协议也是使用三次握手(three-way handshake)机制来建立传输连接的,这与在本章前面介绍的OSI/RM传输层为了避免重复连接而采取的三次握手机制是一样的。具体流程如图10-38所示,其实整体过程在上节的图10-37中有全面的体现,这里仅单独把TCP传输连接建立过程列出来。具体步骤如下:
(1)首先是服务器初始化的过程,从CLOSED(关闭)状态开始通过顺序调用SOCKET、BIND、LISTEN和ACCEPT原语创建Socket套接字,进入LISTEN(监听)状态,等待客户端的TCP传输连接请求。
(2)客户端最开始也是从CLOSED状态开始调用SOCKET原语创建新的Socket套接字,然后在需要再调用CONNECT原语,向服务器发送一个将SYN字段置1(表示此为同步数据段)的数据段(假设初始序号为i),主动打开端口,进入到SYN SENT(已发送连接请求,等待对方确认)状态。
图10-38 TCP传输连接建立的三次握手过程
(3)服务器在收到来自客户端的SYN数据段后,发回一个SYN字段置1(表示此为同步数据段),ACK字段置1(表示此为确认数据段),ack(确认号)=i+1的应答数据段(假设初始序号为j),被动打开端口,进入到SYN RCVD(已收到一个连接请求,但未进行确认)状态。这里要注意的是确认号是i+1,而不是i,表示服务器希望接收的下一下数据段序号为i+1。
(4)客户端在收到来自服务器的SYN+ACK数据段后,向服务器发送一个ACK=1(表示此为确认数据段),序号为i+1,ack=j+1的确认数据段,同时进入ESTABLISHED(连接建立)状态,建立单向连接。要注意的是,此时序号为i+1,确认号为j+1,表示客户端希望收到服务器的下一个数据段的序号j+1。
(5)服务器在收到客户端的ACK数据段后,进入ESTABLISHED状态,完成双向连接的建立。
连接可以由任一方或双方发起,一旦连接建立,数据就可以双向对等地流动,而没有所谓的主从关系。三次握手是连接两端正确同步的充要条件,因为TCP建立在不可靠的分组传输服务之上,报文可能丢失、延迟、重复和乱序,因此协议必须使用超时和重传机制。如果重传的连接请求和原先的连接请求在连接正在建立时到达,或者当一个连接已经建立、使用和结束之后,某个延迟的连接请求才到达,就会出现问题。采用三次握手协议就可以解决这些问题。如客户端发送的ACK数据段就是为了避免因网络延迟而导致的重复连接,因为这时客户端就可通过检查ACK数据段中的确认号就可得知该连接请求是否已失效。
【经验之谈】对比图10-38和本章前面的10.2.2节中的图10-20以看出,总体上TCP传输连接的建立与OSI/RM中TP传输协议的传输连接建立过程既存在相似之处(如三次握手机制),又存在较大区别的。主要表现在:①在OSI/RM中,只有DT TPDU和ED TPDU才有序列号,所以在返回的确认类TPDU中是没有TPDU序号的,所以在图10-20中并没有标注确认TPDU的序列号,而TCP传输连接中,每个数据段(无论是否携带数据)都有序列号,都需要标其对应的序列号;②因为在OSI/RM的传输协议中不同服务原语可以使用不同的特定类型TPDU,所以在OSI/RM的TPDU中不存在像TCP数据段中的ACK、SYN等之类的控制位,因为在TCP协议中所有数据段格式是一样的,不同的只是不同类型的TCP数据段的这些字段的取值不同;③TCP传输连接中使用“确认号”字段与OSI/RM TPDU中的“YR-TU-NR”(你的TPDU序列号)字段的功能是完全一样的,都是显示对端希望接收的下一个数据段序列号,暗示该号码前面的所有数据段均已正确接收。
2. 双方同时主动连接的TCP连接建立过程
正常情况下,传输连接都是由一方主动发起的,但也有可能双方同时主动发起连接,此时就会发生连接碰撞,最终只有一个连接能够建立起来。因为所有连接都是由它们的端点进行标识的。如果第一个连接请求建立起一个由套接字(x,y)标识的连接,而第二个连接也建立了这样一个连接,那么在TCP实体内部只有一个套接字表项。
当出现同时发出连接请求时,则两端几乎在同时发送一个SYN字段置1的数据段,并进入SYN_SENT状态。当每一端收到SYN数据段时,状态变为SYN_RCVD,同时它们都再发送SYN字段置1,ACK字段置1的数据段,对收到的SYN数据段进行确认。当双方都收到对方的SYN+ACK数据段后,便都进入ESTABLISHED状态。图10-39显示了这种同时发起连接的连接过程,但最终建立的是一个TCP连接,而不是两个,这点要特别注意。
图 10-39 同时发起连接的TCP连接建立流程
从图中可以看出,一个双方同时打开的传输连接需要交换4数据段,比正常的传输连接建立所进行的三次握手多交换一个数据段。此外要注意的是,此时我们没有将任何一端称为客户或服务器,因为每一端既是客户又是服务器。
10.3.7 TCP传输连接的释放
TCP 连接建立起来后,就可以在两个方向传送数据流。当 TCP的网络应用进程再没有数据需要发送时,就可以发出关闭连接命令,释放连接。TCP协议是通过发送FIN字段置1的数据段来作为关闭传输连接的命令,关闭本端数据流的,但是本端仍然还可以继续接收来自对端的数据,直到对端也使用了同样的方法关闭那个方向的数据流,这时整个双方传输连接就彻底关闭了。
1. 单方主动关闭的TCP连接释放过程
相对TCP传输连接建立的三次握手过程来说,TCP传输连接的释放过程要稍微复杂一些,需要经过四次握手过程。这是因为TCP的半关闭(half-close)特性造成的,即因这一个TCP连接是全双工(即数据在两个方向上能同时传递),每个方向必须单独地进行关闭。TCP传输连接关闭的原则是:当一方完成它的数据发送任务后就可以发送一个FIN字段置1的数据段来终止这个方向的数据发送;当另一端收到这个FIN数据段后,必须通知它的应用层“对端已经终止了那个方向的数据传送”。而FIN数据段的发送是由应用层调用CLOSE服务原语的结果。TCP连接释放的四次握手过程如图10-40所示,具体描述如下:
(1)一开始,通信双方都处于ESTABLISHED(连接建立)状态。如果客户端认为数据全部发送完了,想结束本次传输连接,则由应用层的对应应用进程调用CLOSE服务原语,然后向服务器发出一个FIN字段置1的数据段(假设此数据段的序号为m),客户端进入FIN WAIT 1状态,等待服务器的确认。
(2)服务器在收到客户端发来的FIN数据段后,确认客户端没有新的数据要发送了,向客户端发送一个ACK字段置1,确认号为m+1(假设此数据段序号为w,服务器与客户端的数据段序号可以不一样),表示前面的数据已全部收到了,然后进入到CLOSE WAIT(关闭等待)状态。与此同时服务器的TCP实体通知对应的应用层进程,释放从客户机到服务器方向的传输连接,进入半关闭状态。但此时服务器仍可以向客户端发送数据段;客户端也可接收来自服务器的数据。而且这可能要持续一段时间,直到服务器的数据也全部发送完。
图10-40 TCP传输连接释放的四次握手过程
(3)当客户端收到服务器的ACK数据段后便进入到了FIN WAIT 2状态,进一步等待服务器发出连接释放的数据段。
(4)当服务器发送完全部的数据后,其对应的应用进程也会通知TCP实体释放此方向的TCP传输连接,向客户机发送FIN字段置1,ACK字段置1,ack=m+1(假设此时的数据段序号已变为w)的确认数据段。这时服务器进入LAST ACK(最后确认)状态,等待客户端的确认。
(5)客户端在收到服务器的FIN+ACK数据段后,向服务器发送一个ACK字段置1,ack=w+1,序列号为m+1的数据段,进入到TIME WAIT状态。但此时TCP连接还没有释放,必须等待2MSL时间(RFC 793建议设MSL为2分钟)后,客户端才进入到CLOSED状态,彻底释放了TCP连接。
(6)服务器在收到客户端发来的ACK数据段后,也进入CLOSED状态,彻底释放连接。完成整个TCP传输连接释放过程。
2. 双方主动关闭的TCP连接释放流程
与可以双方同时建立TCP传输连接一样,TCP传输连接关闭也可以由双方同时主动进行(正常情况下都是由一方发送第一个FIN数据段进行主动连接关闭,另一方被动接受连接关闭),如图10-41所示。具体描述如下:
图10-41 同时主动关闭TCP连接的流程
当两端对应的网络应用层进程同时调用CLOSE原语,发送FIN数据段执行关闭命令时,两端均从ESTABLISHED状态转变为FIN WAIT 1状态。任意一方收到对端发来的FIN数据段后,其状态均由FIN WAIT 1转变到CLOSING状态,并发送最后的ACK数据段。当收到最后的ACK数据段后,状态转变化TIME_WAIT,在等待2MSL后进入到CLOSED状态,最终释放整个TCP传输连接。
TCP传输连接建立与释放详解的更多相关文章
- TCP报文段首部格式详解
TCP首部格式 格式字段详解 源端口.目标端口: 计算机上的进程要和其他进程通信是要通过计算机端口的,而一个计算机端口某个时刻只能被一个进程占用,所以通过指定源端口和目标端口,就可以知道是哪两 ...
- ip头、tcp头、udp头详解及定义,结合Wireshark抓包看实际情况
公司的同事们在分析网页加载慢的问题,忽然使用到了Wireshark工具,我就像发现新大陆一样好奇,赶紧看了看,顺便复习了一下相关协议.上学时学的忘的差不多了,汗颜啊! 报文封装整体结构 mac帧头定义 ...
- [转帖]技术扫盲:新一代基于UDP的低延时网络传输层协议——QUIC详解
技术扫盲:新一代基于UDP的低延时网络传输层协议——QUIC详解 http://www.52im.net/thread-1309-1-1.html 本文来自腾讯资深研发工程师罗成的技术分享, ...
- TCP协议粘包问题详解
TCP协议粘包问题详解 前言 在本章节中,我们将探讨TCP协议基于流式传输的最大一个问题,即粘包问题.本章主要介绍TCP粘包的原理与其三种解决粘包的方案.并且还会介绍为什么UDP协议不会产生粘包. 基 ...
- TCP通讯处理粘包详解
TCP通讯处理粘包详解 一般所谓的TCP粘包是在一次接收数据不能完全地体现一个完整的消息数据.TCP通讯为何存在粘包呢?主要原因是TCP是以流的方式来处理数据,再加上网络上MTU的往往小于在应用处理的 ...
- IP头、TCP头、UDP头详解以及定义
一.MAC帧头定义 /*数据帧定义,头14个字节,尾4个字节*/typedef struct _MAC_FRAME_HEADER{ char m_cDstMacAddress[6]; //目的m ...
- 网络基础知识-TCP/IP协议各层详解
TCP/IP简介 虽然大家现在对互联网很熟悉,但是计算机网络的出现比互联网要早很多. 计算机为了联网,就必须规定通信协议,早期的计算机网络,都是由各厂商自己规定一套协议,IBM.Apple和Micro ...
- TCP/IP协议簇分层详解---转
http://blog.csdn.net/hankscpp/article/details/8611229 一. TCP/IP 和 ISO/OSI ISO/OSI模型,即开放式通信系统互联参考模型(O ...
- 转-tcp建立和释放详解
建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. [更新于2017.01.04 ]该部分内容配图有误,请大家见谅,正确的配图如下,错误配图也不删 ...
随机推荐
- java——HashCode和equal方法
equals()反映的是对象或变量具体的值,即两个对象里面包含的值--可能是对象的引用,也可能是值类型的值. 而hashCode()是对象或变量通过哈希算法计算出的哈希值. 之所以有hashCode方 ...
- 星际SC 地图 Big Game Fort 要塞之战 修正了 BIG GAME 地图的平衡性
星际SC 地图 Big Game Fort 要塞之战 修正了 BIG GAME 地图的平衡性 也适合BIG 1V1 对战 此版本目前不开放1打1造功能
- JS笔记 入门第三
认识DOM 文档对象模型DOM(Document Object Model)定义访问和处理HTML文档的标准方法.DOM 将HTML文档呈现为带有元素.属性和文本的树结构(节点树) 把上面的代码进行分 ...
- Html 小插件10 即时新闻
效果图 <!--即时新闻--><iframe name="alimamaifrm" frameborder="0" marginheight= ...
- Noip2013心态调整
决定成绩的,很多时候可能不是实力,而是心态,一年走来,承受着一次次失败,怀疑,背负着希望与压力,突然发现,只有拥有过,失去过,才可以真正去超越,我希望完成我的梦想,但是唯有放下梦想,才可以走向它. 心 ...
- Maven 添加Jetty
<build> <finalName>springmvc</finalName> <plugins> ...
- Spoj 2713 Can you answer these queries IV 水线段树
题目链接:点击打开链接 题意: 给定n长的序列 以下2个操作 0 x y 给[x,y]区间每一个数都 sqrt 1 x y 问[x, y] 区间和 #include <stdio.h> # ...
- php使用mysql扩展库链接mysql数据库(查询)
php链接数据库可以使用mysql扩展库,mysqli,pdo这几种方式,相比java而言要麻烦一点,因为它不像java那么统一.从代码的难易程度来说php的确要简单许多.步骤大体如下 1.打开数据库 ...
- nginx与ios实现https双向认证
服务端配置 nginx关键配置例如以下: listen 443; server_name localhost; ssl on; ssl_certificate /usr/local/opt/nginx ...
- Windows API中几个函数的总结
[DllImport("User32.dll", EntryPoint = "FindWindow")] public static extern IntPtr ...