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

转载自  深入理解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 接受的连接,这些连接可能占满整个连接队列,客户的主动打开最终将超时。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/324483.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在Docker中运行asp.net core 跨平台应用程序

概述 Docker已经热了有一两年了,而且我相信这不是一个昙花一现的技术,而是一个将深远影响我们日后开发和部署、运营应用系统的一种创新(很多人将其作为devops的一种非常重要的基石)。学习docker的最好方式,莫过于它的…

java中的Queue队列的用法

大家好,欢迎来到雄雄的小课堂,今天给大家分享的是“java中的Queue队列的用法” 前言:好多人对Queue不是很熟悉,毕竟平时也不怎么用,遇到集合要么List要么map这些常用的,殊不知,java中还有个Que…

SpringCloud Netflix Eureka

文章目录一、 Eureka简介Eureka组件二、 Eureka和Zookeeper 对比1 什么是CAP定理2 基于CAP定理比对Eureka和Zookeeper三、 搭建Eureka注册中心1 POM文件2 配置文件application.yml3 启动类4 访问Eureka Server WEB服务管理平台四、 Eureka 服务管理平台介绍1 Eureka Server服务…

使用枚举定义常量更好点儿

大家好,欢迎来到雄雄的小课堂,昨天给大家分享的是“java中的Queue队列的用法示例”,今天,分享的主题是“java中,推荐使用枚举定义常量”。 前言:常量,相信大家多不会陌生,常量值一般…

SpringCloud Netflix Ribbon

文章目录一、 Ribbon简介二、 使用Ribbon开发微服务1 创建springcloud工程 和 commons子模块2 开发服务提供者 - ribbonappservice3 开发服务消费者 - ribbonappclient三、 集中式与进程内负载均衡区别四、 Ribbon常见的负载均衡策略1 Ribbon中的常用负载均衡简介2 配置负载均衡…

Entity Framework Core 生成跟踪列

注意:我使用的是 Entity Framework Core 2.0 (2.0.0-preview2-final)。正式版发布时,功能可能存在变动。 当您设计数据库时,有时需要添加列以跟踪记录何时更改,以及谁进行了更改。例如,您添加以下列: Cre…

老师,我们想看到您的笑容!

“老师,你可以对我们笑笑吗?”今天偶然遇见一位学生在吃饭的路上和我说道。我冲他点了点头,笑道:“好呀”!是啊,我是好久没有把笑声带回班级中了。1目前,4班都在倾尽全力的做项目,试…

阿里巴巴开源 Spring Cloud Alibaba,加码微服务生态建设

转载自 阿里巴巴开源 Spring Cloud Alibaba,加码微服务生态建设 本周,Spring Cloud联合创始人Spencer Gibb在Spring官网的博客页面宣布:阿里巴巴开源 Spring Cloud Alibaba,并发布了首个预览版本。随后,Spring Cloud…

微软发布Azure Stack更多细节,预计9月交付

在近日举行的微软全球合作伙伴大会上,微软宣布Azure Stack现在开始接受预定,预计9月份就可以交付。Azure Stack是微软公有Azure云的私有云实现。和其他私有云提供商不同,微软将把Azure Stack作为一项基于消费的服务,这和其公有云的…

今天你们表现的真棒!!!

12月5日在报告厅举行了“2020级青鸟4班 HTML网页设计大赛”。从一个洁白如纸的空白页面,到布满五彩斑斓样式的cool页面,是同学们一个字母一个单词的敲打出来的。从头脑空白啥都不会说到现在的条理清晰张嘴就来的演讲,是同学们时时刻刻写稿子背…

再有人问你Netty是什么,就把这篇文章发给他

转载自 再有人问你Netty是什么,就把这篇文章发给他 本文基于Netty4.1展开介绍相关理论模型,使用场景,基本组件、整体架构,知其然且知其所以然,希望给大家在实际开发实践、学习开源项目提供参考。 这是一篇万字长文&a…

SpringCloud Netflix Hystrix

文章目录一、 Hystrix简介1 什么是灾难性雪崩效应2 什么是Hystrix二、 服务降级(Ribbon中)三、 服务熔断(Ribbon中)(服务降级的强化版)四、 请求缓存(Ribbon中)(不推荐)(查询频率高,修改频率低时谨慎使用)五、 Openfeign的雪崩处理1 服务降级…

[信息安全] 3.HTTPS工作流程

0. 简单回顾 在前面两篇博客中介绍了密码相关的一些基本工具,包括(对称密码,公钥密码,密码散列函数,混合密码系统,消息认证码码,数字签名,伪随机数,数字证书&#xff09…

如何实现省市关联的下拉列表

前言:在某些电商网站或者APP中,通常填写地址时,会有这样的功能:当我们选择的省份是“山东”时,则城市的下拉列表里所展示的便是山东的城市,当选择的省份是“山西”时,城市的下拉列表所展示的便是…

什么样的事才是有意义的

有时候就在想,真正什么样的事才算有意义呢?

在Azure Container Service创建Kubernetes(k8s)群集运行ASP.NET Core跨平台应用程序

引子 在此前的一篇文章中,我介绍了如何在本地docker环境中运行ASP.NET Core跨平台应用程序,看起来非常不错,不是吗?那么,如果我们希望真正在实际的生产环境去部署和运行这个应用程序,应该怎么做呢&#xf…

这也许是你不曾留意过的 Mybatis 细节

转载自 这也许是你不曾留意过的 Mybatis 细节 Mybatis 可以说是 Java 后端的必备技能,可能你和我一样经常使用到它。但有时 cv 多了,会忘记了一些细节处理,比如为什么要加上这个注解?它的作用是什么等等。 这篇文章是我以前写的…

Nacos整合Ribbon实现客户端负载均衡

启动类去掉RibbonClient注解 10 50 100 1 权重优先调用 注意:启动类加RibbonClient注解 2 集群优先调用 3 元数据基于版本优先调用

ssl1344-Knights【最大独立集,最大匹配,图论】

正题 大意 求在一个扣掉m个格子的n*n的棋盘能放置的最多的马。 解题思路 求最大独立集就好了,最大独立集点数-最大匹配数。最重要的是如何建图。定义一个数组point[i][j]表示点的编号。但是如果这样的话就会O(n4)O(n4)就会超时。现在我们把棋盘从左到右后从上到…

小课堂?小视频?小商店?

今天,没有什么特别内容可更新,就来随便聊聊吧。01雄雄的小课堂这是一个公众号,内容主要有两大类。一类是以分享编程技术为主,一方面是为了提升自己,另一方面也是为了帮助别人,希望阅者有益,平时…