TCP连接建立(三次握手)

如图:

  1. 请求端发送一个SYN到服务器的相应端口,以及初始序号ISN
  2. 服务器发送包含服务器的初始序号的SYN作为应答,同时确认序号设置为客户的ISN+1
  3. 客户将确认序号设置为服务器的ISN+1

最大报文段长度(MSS)

  • 连接建立时,连接的双方都要通告各自的MSS。当建立一个连接时,每一方都有通告它期望接收的MSS选项。如果一方不接收来自另一方的MSS值,则MSS就定为576字节。对于一个以太网,MSS可达1460字节(1460 + IP首部20 + TCP首部20 = 1500)。如果目的IP地址是“非本地的”, MSS通常的默认值是536。
  • MSS让主机限制另一端发送数据报的长度,加上主机也能控制它发送数据报的长度,这将使以较小MTU连接到一个网络的主机避免分段。
  • 如果两端的主机都连接到以太网上,都采用536的MSS, 但中间网络采用296的MTU,也将会出现分段, 使用路径上的MTU发现机制是关于这个问题的唯一方法。

同时打开

一般情况下,连接建立时是一方发送SYN,另一方发送SYN+ACK, 但极个别情况下,有可能两个应用程序几乎同时向对方发送SYN,这就叫做同时打开。同时打开需要双方都使用彼此熟知的端口,而不是一般情况下只需要客户使用服务器的知名端口。

TCP的同时打开的状态变迁图如下:



两端几乎同时发送SYN,并进入SYN_SENT状态。当每一端收到SYN时,状态变为SYN_RCVD,同时它们都再发SYN并对收到的SYN进行确认。当双方都收到SYN及相应的ACK时,状态都变迁为ESTABLISHED。

呼入连接请求队列

有可能出现当服务器在创建一个新的进程时,或操作系统正忙于处理优先级更高的进程时,到达多个连接请求,当服务器处于忙时,TCP是如何处理这些呼入的连接请求?

在伯克利的TCP实现中采用以下规则:

  1. 正等待连接请求的一端有一个固定长度的连接队列,该队列中的连接已被TCP接受(即三次握手已完成),但还没有被应用层所接受。注意区分TCP接受一个连接是将其放入队列,而应用层是将其从该队列中移出。
  2. 应用层将指明该队列的最大长度,这个值称为积压值。它的取值范围是0~5之间的整数。
  3. 当一个连接请求到达时,TCP使用一个算法,来确定是否接收这个连接。
  4. 如果对于新的连接请求,该TCP监听的端点的连接队列中还有空间,TCP模块将对这个SYN进行确认并完成连接的建立。但应用层只有在三次握手中的第三个报文段才能知道这个新连接。另外,当客户进程的主动打开成功但服务器的应用层还不知道这个新的连接时,它可能会认为服务器进程已经准备好接收数据了(如果发生这种情况,服务器的TCP仅将接收的数据放入缓冲队列)。
  5. 如果对于新的连接请求,连接队列已没有空间,TCP将不理会收到的SYN,也不发回任何报文段(即不发回RST),如果应用层不能及时接受已被TCP接受的连接,这些连接可能占满整个连接队列,客户的主动打开将最终超时。

    当队列已满时,TCP将不理会收到的SYN,也不发回任何报文段(即不发回RST),因为这是一个软错误,而不是一个硬错误。通常队列已满是由于应用程序或操作系统忙造成的,这样可防止应用程序对传入的连接进行服务。这个条件在很短的时间内可以改变。但如果服务器的TCP以系统复位作为响应,客户进程的主动打开将被废弃。由于不应答SYN,服务器程序迫使客户TCP随后重传SYN,以等待连接队列有空间接受新的连接。

TCP连接终止(四次握手)

既然一个TCP连接是全双工的(即数据在两个方向上都能传递),因此每个方向都必须单独进行关闭。这原则就是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向上的连接。当一端收到一个FIN,它必须通知应用层另一端已经终止了那个方向的数据传送。

如下图:

半关闭

TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。这就是所谓的半关闭。

如下图:

2MSL等待状态

TIME_WAIT状态也称为2MSL等待状态。每个具体TCP实现必须选择一个报文段最大生存时间MSL。它是任何报文段被丢弃前在网络内的最长时间。

为什么要有TIME_WAIT状态?

  • 因为终止连接的一方发送的最后的一个ACK可能会丢失,另一端超时并重发最后的FIN, 这样终止连接的一方可以再次发送最后的ACK

为什么是2MSL?

  • 最后一个ACK存在的时间最多为MSL,如果ACK丢失,然后接收端超时并重发FIN,这个FIN最多存在时间又是MSL,而TIME_WAIT状态需要等待这个连接中的所有分组都消失,所以需要等待2ML
  • 2MSL时间后这个连接的所有分组都会消失,不会干扰到接下来相同socket对建立的连接。

TCP在2MSL等待期间,定义这个连接的插口(客户的IP地址和端口号,服务器的IP地址和端口号)不能再被使用,这个连接只能在2MSL结束后才能再被使用。如果我们终止一个已经建立连接的服务器程序,并试图立即重启这个服务器程序,服务器程序不能把它的这个熟知端口赋值给它的端点,因为那个端口是出于2MSL连接的一部分。

我们可以以-A标记来设置SO_REUSEADDR,这样可以使服务器程序使用之前的端口,但它不能主动打开之前的相同端口的客户程序,应为那个连接的插口对仍处于2MSL等待状态。但我们如果让那个客户程序来主动打开这个服务器程序是会成功的,因为大多数的伯克利实现支持一个新的连接请求到达仍处于TIME_WAIT状态的连接。

复位报文段

一般说来,无论何时一个报文段发往指定的连接出现错误,TCP都会发出一个复位报文段。

产生复位的几种常见情况是:

  • 到不存在的端口的连接请求;
  • 异常终止一个连接;
  • 检测半打开连接。

    如果一端已经关闭或异常终止连接而另一方却还不知道,我们将这样的连接成为半打开连接。

    同时关闭

    两边都执行主动关闭也是有可能的,TCP协议也允许这样的同时关闭。

    如下图:

部分问题

  1. 为什么服务器对客户FIN的ACK不和自己的FIN合并(即终止连接不是三次握手)?

    因为发送客户FIN的ACK通常是收到FIN就立刻发送,但这是服务器不一定要关闭自己这端的连接,还可能需要发送数据(半关闭),所以不一定要发送FIN。
  2. 分析处于TIME_WAIT状态的主机收到使其进入此状态的重复的FIN时所发生的情况

    发送ACK,重启定时器。

TCP连接建立和终止小结的更多相关文章

  1. 动手学习TCP:TCP连接建立与终止

    TCP是一个面向连接的协议,任何一方在发送数据之前,都必须先在双方之间建立一条连接.所以,本文就主要看看TCP连接的建立和终止. 在开始介绍TCP连接之前,先来看看TCP数据包的首部,首部里面有很多重 ...

  2. TCP连接建立与终止,及状态转换

    TCP连接建立 三路握手 三路握手发生在客户端发起connect请求到服务端accept返回中,在三路握手发生前,服务端必须准备好接受外来连接,这通常通过服务端调用 (socket.bind.list ...

  3. 关于TCP连接建立与终止那点事

    0. 前言 最近在处理公司遗留项目的时候发现自己对TCP协议一点都不懂,所以补了点关于TCP连接的建立和终止的内容,这里简单写下自己了解的部分,省略了报文序号确认序号这些无关的字段,主要讨论TCP状态 ...

  4. 传输控制协议(TCP) -- 连接建立及终止过程

    TCP简介 相对于不可靠.无连接的用户数据报协议(User Datagram Protocol, UDP),传输控制协议(Transmission Control Protocol, TCP)是可靠的 ...

  5. TCP连接建立和关闭中的疑难点

    TCP连接建立和关闭中的疑难点 作者:夏语岚    撰写日期:2011-10-29 近日在阅读<Unix网络编程>,以前在<计算机网络>课程中学到TCP,当时只是简单了解了TC ...

  6. TCP连接建立与关闭

    http://hi.baidu.com/psorqkxcsfbbghd/item/70f3bd91943b9248f14215cd TCP连接建立与关闭 TCP 是一个面向连接的协议,无论哪一方向另一 ...

  7. tcp、http 学习小结

    tcp.http 学习小结 前言 最近因为cdn的一个问题,困扰了自己好久.因为需要统计网站访问的成功数,而且要求比较精确.目前的实现不能满足要求,因为没有区别访问成功与否,也没有对超时做处理.期间解 ...

  8. 计算机网络传输层之TCP协议(tcp协议特点、tcp报文段首部格式、tcp连接建立---三次握手、tcp连接释放---四次握手)

    文章转自:https://blog.csdn.net/weixin_43914604/article/details/105516090 学习课程:<2019王道考研计算机网络> 学习目的 ...

  9. 《TCP/IP详解 卷一》读书笔记-----TCP连接建立

    1.在每个TCP报文段中,头部的flag字段里的SYN,FIN,RST,PSH可以多个有效,并没有限定为必须只有一个 2.TCP连接建立过程: 1)客户端发送一个SYN报文段,其中包含了客户端要传送的 ...

随机推荐

  1. .Net使用RabbitMQ详解

    序言 这里原来有一句话,触犯啦天条,被阉割!!!! 首先不去讨论我的日志组件怎么样.因为有些日志需要走网络,有的又不需要走网路,也是有性能与业务场景的多般变化在其中,就把他抛开,我们只谈消息Rabbi ...

  2. ElasticSearch 5学习(2)——Kibana+X-Pack介绍使用(全)

    Kibana是一个为 ElasticSearch 提供的数据分析的 Web 接口.可使用它对日志进行高效的搜索.可视化.分析等各种操作.Kibana目前最新的版本5.0.2,回顾一下Kibana 3和 ...

  3. 【分布式】Zookeeper的Leader选举

    一.前言 前面学习了Zookeeper服务端的相关细节,其中对于集群启动而言,很重要的一部分就是Leader选举,接着就开始深入学习Leader选举. 二.Leader选举 2.1 Leader选举概 ...

  4. Android来电监听和去电监听

    我觉得写文章就得写得有用一些的,必须要有自己的思想,关于来电去电监听将按照下面三个问题展开 1.监听来电去电有什么用? 2.怎么监听,来电去电监听方式一样吗? 3.实战,有什么需要特别注意地方? 监听 ...

  5. ldap部署相关,ldap双机\LAM配置管理\ldap备份还原

    前言 接之前我的文章,django+ldap+memcache实现单点登录+统一认证 就单点登录实现过程进行详细记录,ldap是一切的基础,可以把它理解成一个读强写弱的文件类型数据库,统一认证我们通过 ...

  6. Entity Framework入门系列(1)-扯淡开篇

    这是我在Cnblogs上的第一个系列,但愿能坚持下去: 惯例索引 Entity Framework入门系列(1)-开篇兼索引: Entity Framework入门系列(2)-初试Code First ...

  7. asp.net mvc View视图相关

    1.0 @helper语法 @helper语法可以定义可重复使用的帮助器方法: 例如 @helper methodName(type paramName,...){ //todo } 调用:@meth ...

  8. Java中的多线程你只要看这一篇就够了

    学习Java的同学注意了!!! 学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:279558494 我们一起学Java! 引 如果对什么是线程.什么是进程仍存有疑惑, ...

  9. 《连载 | 物联网框架ServerSuperIO教程》-4.如开发一套设备驱动,同时支持串口和网络通讯。附:将来支持Windows 10 IOT

    1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...

  10. 【干货分享】前端面试知识点锦集03(JavaScript篇)——附答案

    三.JavaScript部分 1.谈谈你对Ajax的理解?(概念.特点.作用) AJAX全称为“Asynchronous JavaScript And XML”(异步JavaScript和XML) 是 ...