LINUX网络编程:TCP(1)

embedded/2024/9/23 13:14:41/

目录

1.认识Tcp的报头

2.确认应答机制(ACK)

序号与确认序号

捎带应答

3.超时重传机制

4.Tcp连接管理

三次握手

为什是三次握手

四次挥手

 理解TIMEWAIT


1.认识Tcp的报头

源端口和目的端口号没什么说的

32位的序号和确认序号,之后会介绍。

4位首部长度表示的是Tcp报头的长度,但是4位长度最多也就能表示15个字节,即使不算选项,也有20个字节,这是因为首部长度的单位是4字节,所以四位首部长度可以表示的长度是 4 * 15 = 60字节。

URG ACK PSH 都是tcp协议的选项,代表着不同的Tcp协议类型

剩下的字段后面介绍。

2.确认应答机制(ACK)

Tcp是保证可靠性的,确认应答机制就是保证可靠性的一种机制。

其实这就是在日常生活中很常见的方法。

例:小明:小红我喜欢你,你愿意做我女朋友吗?

        小红:就你这样长的太丑了,还是算了吧。

这个例子就是确认应答机制,怎么理解呢,

小红对小明的请求进行了回复(ACK),就说明小明的请求小红收到了。

到此故事结束。

序号与确认序号

Tcp是传输控制协议,发送数据需要先将数据交给tcp的发送缓冲区,可能会将数据拆分一个一个包。交给操作系统,系统在发送,在到达对端的时候要保证包的顺序要和发送前一致,所以必须要有序号来标识每个包。

Tcp是面向字节流的,他会对每个字节进行编号,ACK返回时,确认序号 = 序号 + 1,为了告诉发送者,下次该从哪个字节开始发。

这里可能就有一个问题了,可能有人觉得确认序号就是一个摆设,明明一个序号就能搞定的事,还整一个确认序号。

但是在捎带应答的场景下一个序号就不够用。

捎带应答

捎带应答就是,在ACK向发送者返回时,碰巧接受者也想向发送者发送信息,那么这两条报文就会合二为一,因为ACK就是一个报头,他没有数据,碰巧我正想发送数据,在ACK加上数据不就是两全其美了吗。

在这种情况下,序号表示发server送包的顺序,确认序号表示clint下次发送开始的位置。

3.超时重传机制

这也是tcp保证可靠性的一种方式,在一段时间内,如果没收到ACK就会,重新发送一次数据。

没有收到应答是有两种可能1.真的丢包了  2.包收到但ACK丢了,这种情况就需要tcp把收到序号相同的包直接丢弃。

这个特殊的时间间隔是根据网络状况动态计算的。

4.Tcp连接管理

三次握手

服务端状态转化:
[CLOSED -> LISTEN] 服务器端调用listen后进入LISTEN状态, 等待客户端连接;
[LISTEN -> SYN_RCVD] 一旦监听到连接请求(同步报文段), 就将该连接放入内核等待队列中, 并向客户端发送SYN确认报文.
[SYN_RCVD -> ESTABLISHED] 服务端一旦收到客户端的确认报文, 就进入ESTABLISHED状态, 可以进行 读写数据了
客户端状态转化:
[CLOSED -> SYN_SENT] 客户端调用connect, 发送同步报文段;
[SYN_SENT -> ESTABLISHED] connect调用成功, 则进入ESTABLISHED状态, 开始读写数据;

三次握手是保证可靠性的不是三次握手连接100%能建立成功

前两次握手报文丢失,客户端和服务端的服务器状态都不是ESTABUSHED,超时重传即可。

但是最后一次握手ACK发出去的时候客户端就认为自己连接已经建立成功了,如果这个ACK丢失,服务器连接没建立成功,客户端认为自己连接建立成功,客户端直接向服务器发送数据了,这时候服务器会向客户端发送RST报文(reset)重新进行三次握手

为什是三次握手

1.三次握手双方都有一次完整的收发,保证了网络是健康的 而且 双方都是全双工的。

2.保证了双方的Tcp都是愿意通信的,SYN就相当于客户端对服务器说你愿意和我通信吗? ACK就是我愿意

四次挥手

在这里补充一下,三次握手和四次挥手都是通讯细节,这些都是操作系统的工作。

服务端状态转化:
[ESTABLISHED -> CLOSE_WAIT] 当客户端主动关闭连接(调用close), 服务器会收到结束报文段, 服务器 返回确认报文段并进入CLOSE_WAIT;
[CLOSE_WAIT -> LAST_ACK] 进入CLOSE_WAIT后说明服务器准备关闭连接(需要处理完之前的数据); 当服务器真正调用close关闭连接时, 会向客户端发送FIN, 此时服务器进入LAST_ACK状态, 等待最后一个 ACK到来(这个ACK是客户端确认收到了FIN)
[LAST_ACK -> CLOSED] 服务器收到了对FIN的ACK, 彻底关闭连接.
客户端状态转化:
[ESTABLISHED -> FIN_WAIT_1] 客户端主动调用close时, 向服务器发送结束报文段, 同时进入
FIN_WAIT_1;
[FIN_WAIT_1 -> FIN_WAIT_2] 客户端收到服务器对结束报文段的确认, 则进入FIN_WAIT_2, 开始等待服务器的结束报文段;
[FIN_WAIT_2 -> TIME_WAIT] 客户端收到服务器发来的结束报文段, 进入TIME_WAIT, 并发出LAST_ACK;
[TIME_WAIT -> CLOSED] 客户端要等待一个2MSL(Max Segment Life, 报文最大生存时间)的时间, 才会 进入CLOSED状态

问题:客户端关闭连接,服务器还能给客户端发消息吗?

答案是可以的 ,tcp是有接受和发送两个缓冲区的,一般情况下关闭连接直接close(fd)两个缓冲区会直接关闭,但shutdown接口是可以只关闭一个缓冲区的。

参数how,设置为SHUT_RD关闭接受缓冲区,SHUT_WR关闭发送缓冲区,SHUT_RDWR关闭接受和发送两个缓冲区。

 理解TIMEWAIT

先启动一个服务,然后ctrl + c将服务终止,在将服务启动,我们会发现,bind竟然失败了。 

这是因为Tcp规定,主动关闭连接的一方要等待两个MSL(maximum segment lifetime)时间在从TIMEWAIT状态变为closed。

可以使用cat /proc/sys/net/ipv4/tcp_fin_timeout 查看MSL时间,默认60秒。

这么做的目的是为了防止,服务器关闭了,却还有报文在网络中传输。

如果服务器立马重启,收到了这种报文不就出问题了吗,这种报文已经过期了,丢掉都一点都不可惜。

serverTCP连接没有完全断开之前不允许重新监听, 某些情况下可能是不合理的。

使用setsocketopt接口可以解决这种问题。

int opt = 1;
::setsockopt(_listenfd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt));

理解CLOSE_WAIT状态

服务器启动,客户端与服务器建立连接,客户端退出。

查看服务器连接的状态,发现有很多的CLOSE_WAIT连接,出现这种情况就是服务器忘记关闭文件描述符了,导致四次挥手不能完成,连接的状态就卡在CLOSE_WAIT这里了。


http://www.ppmy.cn/embedded/114379.html

相关文章

Android 系统下:普通应用无缝安装,Launcher 应用安装遭遇罕见障碍解析

目录 一、场景 1.1 错误分析 1.2 解决方法尝试 1.2.1 检查应用的安装位置 1.2.2 使用ADB安装 1.2.3 检查APK的签名 1.2.4 检查可用的内部存储空间 1.2.5 将应用程序安装到设备的内部存储空间 1.2.6 重置设备(谨慎使用) 1.2.7 获取Root权限&…

链动321模式开发系统解析源码

链动321模式是一种结合了区块链技术、动态激励机制与“321”运营模式的新型电商架构。该模式通过激励用户分享和推广,实现用户、企业和平台的共赢,具有独特的商业逻辑和高效的运营机制。以下是对链动321模式的详细解析: 系统特点 裂变迅速&am…

HarmonyOS NEXT 封装实现好用的网络模块(基于最新5.0的API12)

在 HarmonyOS-NEXT 开发中,网络请求是应用开发中不可或缺的一部分。为了提高开发效率和代码复用性,我们可以封装一个好用的网络模块组件。本文将介绍如何在 HarmonyOS-NEXT 中封装一个功能强大且易于使用的网络模块组件。 封装目的 网络模块使用的频率最…

变量的作用域和生命周期

大家好我是清墨,欢迎收看本期文章。 1. 数据存储的 3 要素 计算机程序在存储数据时必须跟踪 3 个基本属性: 信息存储在何处,在什么地方定义变量,决定了信息存储在何处存储的值是多少,值是多少是通过赋值语句&#xff…

Java 基础知识九(网络编程)

UDP DatagramSocket:通讯的数据管道 -send 和receive方法 -(可选,多网卡)绑定一个IP和Port DatagramPacket -集装箱:封装数据 -地址标签:目的地IPPort package org.example.net;import java.net.DatagramPacket; import java.net.DatagramSocket; import java.n…

Matlab R2024B软件安装教程

一、新版本特点 MATLAB R2024B版本带来了众多新特性和改进,旨在提升用户的内容创作体验和工程效率。以下是该版本的一些主要特点: 1. 性能提升和优化:R2024B版本在性能上进行了显著优化,无论是在提问、回答问题、发布新技巧还是…

mybatisplus中id生成策略

使用Tableld(value,type) 1.typeIdType.AUTO自增主键 2.typeIdType.ASSIGN,雪花算法生成 mybatisplus id生成策略全局配置 配置表前缀以及id生成策略 mybatis-plus:global-config:db-config:id-type: autotable-prefix: :t_

.Net Core 生成管理员权限的应用程序

创建一个ASP.NET Core Web API项目 给解决方案设置一个名称 选择一个目标框架,这里选择的是 .NET 8.0框架 在Porperties文件夹中添加一个app.manifest文件 设置app.manifest文件属性,生成操作设置为嵌入的资源 双击解决方案名称,编辑WebAppli…