深入理解 TCP IP 协议 -TCP 建立与终止连接

本贴最后更新于 2354 天前,其中的信息可能已经时移世易

深入理解 TCP/IP 协议-TCP 建立与终止连接

一、引言

  TCP 是一个面向连接的协议。无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。连接创建与终止的状态变化图如下:

二、三次握手建立连接

过程如下:

  • 客户端发送一个 SYN 数据包指明客户端打算连接服务器的端口,初始化序号(ISN)为 m。
  • 服务器发回包含服务器的 ISN 作为应答(值为 n)。同时,将确认序号设置成客户端 ISN+1(m+1)来作为对客户端 SYN 的确认。
  • 客户端发送一个 ACK 数据包,ack=n+1, 作为对服务器的 SYN 的确认。

1. 为什么是三次握手,而不是两次

  网络是不可靠的,数据包是可能丢失的。假设没有第三次确认,客户端向服务端发送了 SYN,请求建立连接。由于延迟,服务端没有及时收到这个包。于是客户端重新发送一个 SYN 包。回忆一下介绍 TCP 首部时提到的序列号,这两个包的序列号显然是相同的。假设服务端接收到了第二个 SYN 包,建立了通信,一段时间后通信结束,连接被关闭。这时候最初被发送的 SYN 包刚刚抵达服务端,服务端又会发送一次 ACK 确认。由于两次握手就建立了连接,此时的服务端就会建立一个新的连接,然而客户端觉得自己并没有请求建立连接,所以就不会向服务端发送数据。从而导致服务端建立了一个空的连接,白白浪费资源。

  TCP 是双通道,需要双向确定。只有两次握手,客户端知道了服务器收到了,服务器不知道客户端收到了,联想打电话。通讯系统中的占拜庭将军问题。

2. 最大报文段长度

  最大报文段长度(MSS)表示 TCP 传往另一端的最大块数据的长度。当一个连接建立时,连接的双方都要通告各自的 MSS。在三次握手的时候 SYN 的 TCP 首部中的可选字段确定。以太网的默认长度为 1460。

三、四次握手关闭连接(正常状态)

  建立一个连接需要三次握手,而终止一个连接要经过 4 次握手。这由 TCP 的半关闭 (half-close) 造成的。一个 TCP 连接是全双工(即数据在两个方向上能同时传递),因此每个方向必须单独地进行关闭。

  • 主动方想要关闭连接,发送 FIN 包给被动方,序号为 m
  • 被动方接收到主动方发送的 FIN 包,知道了对方要关闭连接,发送 ACK 确认包,序号 m+1。主动方连接关闭。
  • 等待片刻(处于半关闭状态),在此期间(finwait2,closewait)。被动方发送最后的数据,主动方接收最后的数据。
  • 被动方确认要关闭连接,发送 FIN 包。序号 n。
  • 主动方等待片刻(接收网络中,还未到达的数据包),发送 ACK 确认包。序号 n+1。到此连接关闭。

1.TCP 的半关闭状态

  TCP 提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。如主动方处于 fin_wait2 状态。

2.TIME_WAIT 状态

  TIMEWAIT 状态也称为 2MSL 等待状态。每个具体 TCP 实现必须选择一个报文段最大生存时间 MSL( Maximum Segment Lifetime)。它是任何报文段被丢弃前在网络内的最长时间。因为 TCP 报文段以 IP 数据报在网络内传输,而 IP 数据报则有限制其生存时间的 TTL 字段。在实际应用中,对 I P 数据报 TTL 的限制是基于跳数,而不是定时器。   在处于 2MSL 等待状态的 socket(客户端 IP 与端口,服务器 IP 与端口) 不能再被使用。但在实际的使用中,允许一个新的连接请求到达仍处于 timewait 状态的连接,只要新的序号大于该连接的前一个连接的最后序号。

四、正常状态抓包

下面是一次完整的 tcp 建立连接,发送数据,关闭连接过程

该过程为,3 次握手建立连接,一次数据发送,4 次握手关闭连接

五、异常情况

出现异常的时候,服务器通常通过复位报文来通告,复位报文为 tcp 数据包类型设置为 rst。

1. 连接超时或到达不存在的端口 / 服务器

当服务器端没有开或网络问题,会出现连接超时的情况。抓包如下:

客户端尝试 3 三次来连接,有时候服务器端会发送 rst 数据包。

2. 异常终止一个连接

  在 TCP 通讯中。如果通讯双方应为某种原因(如突然断电等)关闭连接时候一方(如 A)没有发送 fin 数据包。另一端 (如 B) 不知道对方已经关闭了连接。再次发送数据的时候,异常关闭的一方,可能会返回一个 rst 数据包。通知异常关闭。如果一方已经关闭或异常终止连接而另一方却还不知道,我们将这样的 TCP 连接称为半打开 (Half Open) 的。

3. 同时打开

  两个应用程序同时彼此执行主动打开的情况是可能的。每一方必须发送一个 SYN,且这些 SYN 必须传递给对方。这需要每一方使用一个对方熟知的端口作为本地端口。同时打开的状态迁移图不同于正常状态的三次握手,该情况下需要进行 4 次握手。如图:

4. 同时关闭

  我们在以前讨论过一方(通常但不总是客户方)发送第一个 FIN 执行主动关闭。双方都执行主动关闭也是可能的,TCP 协议也允许这样的同时关闭(simultaneous close)。在同时关闭的时候,双方都进入 time_wait 状态,如图:

六. TCP 服务器设计

  大多数的 TCP 服务器进程是并发的。当一个新的连接请求到达服务器时,服务器接受这个请求,并调用一个新进程来处理这个新的客户请求。

1. 接入连接请求队列

  一个并发服务器调用一个新的进程来处理每个客户请求,因此处于被动连接请求的服务器应该始终准备处理下一个呼入的连接请求。那正是使用并发服务器的根本原因。但仍有可能出现当服务器在创建一个新的进程时,或操作系统正忙于处理优先级更高的进程时,到达多个连接请求。当服务器正处于忙时,TCP 是如何处理这些呼入的连接请求?TCP 有这样一个队列来临时存放这些连接 - 接入连接请求队列。处理方式如下:

  • 正等待连接请求的一端有一个固定长度的连接队列,该队列中的连接已被 TCP 接受(即三次握手已经完成),但还没有被应用层所接受。注意区分 TCP 接受一个连接是将其放入这个队列,而应用层接受连接是将其从该队列中移出。
  • 应用层将指明该队列的最大长度,这个值通常称为积压值 (backlog)。
  • 当一个连接请求(SYN)到达时, TCP 使用一个算法,根据当前连接队列中的连接数来确定是否接收这个连接。积压值说明的是 TCP 监听的端口已被 TCP 接受而等待应用层接受的最大连接数。
  • 如果对于新的连接请求,该 TCP 监听的端口的连接队列中还有空间,TCP 模块将对 SYN 进行确认并完成连接的建立。此时,应用层不一定知道该新的连接,如果对方发送数据,这些数据将放入缓冲队列中。
  • 如果对于新的连接请求,连接队列中已没有空间,TCP 将不理会收到的 SYN。也不发回任何报文段(即不发回 RST)。如果应用层不能及时接受已被 TCP 接受的连接,这些连接可能占满整个连接队列,客户的主动打开最终将超时。
  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:SymSoloVditor思源笔记

    1063 引用 • 3455 回帖 • 160 关注
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3200 引用 • 8216 回帖
  • tcp-ip
    1 引用

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • 一些有用的避坑指南。

    69 引用 • 93 回帖
  • 分享

    有什么新发现就分享给大家吧!

    248 引用 • 1794 回帖 • 2 关注
  • jsoup

    jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据。

    6 引用 • 1 回帖 • 488 关注
  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    107 引用 • 153 回帖
  • OnlyOffice
    4 引用 • 23 关注
  • WiFiDog

    WiFiDog 是一套开源的无线热点认证管理工具,主要功能包括:位置相关的内容递送;用户认证和授权;集中式网络监控。

    1 引用 • 7 回帖 • 609 关注
  • 大疆创新

    深圳市大疆创新科技有限公司(DJI-Innovations,简称 DJI),成立于 2006 年,是全球领先的无人飞行器控制系统及无人机解决方案的研发和生产商,客户遍布全球 100 多个国家。通过持续的创新,大疆致力于为无人机工业、行业用户以及专业航拍应用提供性能最强、体验最佳的革命性智能飞控产品和解决方案。

    2 引用 • 14 回帖
  • 脑图

    脑图又叫思维导图,是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。

    32 引用 • 99 回帖
  • Kafka

    Kafka 是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是现代系统中许多功能的基础。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。

    36 引用 • 35 回帖 • 1 关注
  • flomo

    flomo 是新一代 「卡片笔记」 ,专注在碎片化时代,促进你的记录,帮你积累更多知识资产。

    6 引用 • 143 回帖
  • WebClipper

    Web Clipper 是一款浏览器剪藏扩展,它可以帮助你把网页内容剪藏到本地。

    3 引用 • 9 回帖
  • Google

    Google(Google Inc.,NASDAQ:GOOG)是一家美国上市公司(公有股份公司),于 1998 年 9 月 7 日以私有股份公司的形式创立,设计并管理一个互联网搜索引擎。Google 公司的总部称作“Googleplex”,它位于加利福尼亚山景城。Google 目前被公认为是全球规模最大的搜索引擎,它提供了简单易用的免费服务。不作恶(Don't be evil)是谷歌公司的一项非正式的公司口号。

    49 引用 • 192 回帖
  • SQLite

    SQLite 是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是全世界使用最为广泛的数据库引擎。

    5 引用 • 7 回帖
  • Gitea

    Gitea 是一个开源社区驱动的轻量级代码托管解决方案,后端采用 Go 编写,采用 MIT 许可证。

    5 引用 • 16 回帖 • 2 关注
  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖 • 4 关注
  • 微信

    腾讯公司 2011 年 1 月 21 日推出的一款手机通讯软件。用户可以通过摇一摇、搜索号码、扫描二维码等添加好友和关注公众平台,同时可以将自己看到的精彩内容分享到微信朋友圈。

    133 引用 • 796 回帖 • 1 关注
  • 旅游

    希望你我能在旅途中找到人生的下一站。

    95 引用 • 901 回帖
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖
  • CodeMirror
    2 引用 • 17 回帖 • 162 关注
  • 禅道

    禅道是一款国产的开源项目管理软件,她的核心管理思想基于敏捷方法 scrum,内置了产品管理和项目管理,同时又根据国内研发现状补充了测试管理、计划管理、发布管理、文档管理、事务管理等功能,在一个软件中就可以将软件研发中的需求、任务、bug、用例、计划、发布等要素有序的跟踪管理起来,完整地覆盖了项目管理的核心流程。

    6 引用 • 15 回帖 • 14 关注
  • MyBatis

    MyBatis 本是 Apache 软件基金会 的一个开源项目 iBatis,2010 年这个项目由 Apache 软件基金会迁移到了 google code,并且改名为 MyBatis ,2013 年 11 月再次迁移到了 GitHub。

    173 引用 • 414 回帖 • 364 关注
  • Hibernate

    Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库。

    39 引用 • 103 回帖 • 726 关注
  • Sandbox

    如果帖子标签含有 Sandbox ,则该帖子会被视为“测试帖”,主要用于测试社区功能,排查 bug 等,该标签下内容不定期进行清理。

    432 引用 • 1250 回帖 • 595 关注
  • TGIF

    Thank God It's Friday! 感谢老天,总算到星期五啦!

    290 引用 • 4494 回帖 • 653 关注
  • 音乐

    你听到信仰的声音了么?

    62 引用 • 512 回帖
  • 创业

    你比 99% 的人都优秀么?

    82 引用 • 1395 回帖
  • 强迫症

    强迫症(OCD)属于焦虑障碍的一种类型,是一组以强迫思维和强迫行为为主要临床表现的神经精神疾病,其特点为有意识的强迫和反强迫并存,一些毫无意义、甚至违背自己意愿的想法或冲动反反复复侵入患者的日常生活。

    15 引用 • 161 回帖