TCP常见问题

news2025/1/23 10:42:44

一、TCP连接的保活机制

在一段时间内,如果TCP连接两方都没有数据交互,TCP的保活机制**(TCP keepalive)**会起作用,每隔一个时间段会发送一个探测报文,如果连着好几个探测报文都没有得到相应,则会认为当前TCP连接已经GG,系统内核会将错误信息通知给上层应用程序。
在这里插入图片描述

二、TCP连接一端宕机和进程崩溃分别会发生什么?

在没有开启TCP keepalive的情况下

  • 宕机:主机崩了,另外一端是感知不到的,另外因为没有开启保活机制,也没有数据交互,所以一直会处以ESTABLISHD状态。
  • 进程崩溃:进程崩溃了,操作系统可以感知到,所以操作系统回给对方发送FIN报文,进行四次挥手断开连接。

客户端主机宕机,又立即重启

  • 客户端没有进程监听对应的端口号,会发送RST报文,重置该连接。
  • 客户端有进程监听改端口,但是之前的TCP连接对应的结构体已丢失,所以找不到对应的socket,所以回RST,重置该连接。

客户端宕机,没有重启
服务端会发送发送的探测报文超时次数达到一定阈值,就会认为该TCP连接有问题。

三、被动关闭方因网络延时导致在第三次握手的FIN比之前正常发送的数据包早到达主动关闭方会发生什么?

在这里插入图片描述
就是当主动关闭方收到FIN报文时是怎样处理的。根据源码分析,在FIN_WAIT2状态时会检查FIN报文的序列号,如果前面还有报文还未到达,所以此FIN是乱序的,因此会加入乱序队列。等到有新的报文到达时,会判断乱序报文队列里面有无可用数据,会在乱序队列中找与新到报文顺序的报文,查看此报文是否是FIN报文,如果是,则会进入TIME_WAIT状态。
在这里插入图片描述

四、客户端掉线了,服务端不知道,客户端重启后重新发送SYN请求服务端会作何处理?

在三次握手时初始的序列号是随机的,所以一般情况下,客户端重新发送的SYN请求中的初始化序列号不是当前服务端期望收到序列号,服务端会回复RST。

五、如何不杀死进程关闭一个TCP连接?

伪造一个相同的四元组,发送的的RST报文序列号落在对端可接收的滑动窗口序列范围内。
伪造相同的四元组容易,如何获取到对端期望的下一个报文序列号呢?
根据问题四,可以先给对端发送一个SYN请求,服务端会回复challenge ACK,这个ACK的确认号,便是服务端期望接收的下一个报文序列号,然后使用此序列号作为发送RST的序列号,服务端收到后会释放连接。
在 Linux 上有个叫 killcx 的工具,就是基于上面这样的方式实现的,它会主动发送 SYN 包获取 SEQ/ACK 号,然后利用 SEQ/ACK 号伪造两个 RST 报文分别发给客户端和服务端,这样双方的 TCP 连接都会被释放,这种方式活跃和非活跃的 TCP 连接都可以杀掉。

六、SYN报文什么情况下会被丢弃?

  • accept或者SYN队列(没有开启cookies)满了的时候;
  • 开启tcp_tw_recycle,在NET环境下没可能会被丢弃;

在tcp连接中有两个参数:

  • net.ipv4.tcp_tw_resuse:开启后客户端(发起连接方),connect时会随机找到一个TIME_WAIT时间超过1S的连接给新连接使用。
  • net,ipv4.tcp_tw_recycle:允许处于TIME_WAIT状态的连接被快速收回。

要使得这两个选项生效,有一个前提条件,就是要打开 TCP 时间戳,即 net.ipv4.tcp_timestamps=1(默认即为 1)。
**PAWS机制:**收发两方维护最近一次收到数据的时间戳,要求收到的数据包时间戳是递增的,如果不是递增,说明此数据包过期。

当开启net,ipv4.tcp_tw_recycle和时间戳时会开启一种叫per-host的PWAS机制:
对IP做PAWS检查,不是对IP+端口四元组做PAWS检查。因此客户端环境使用了NAT网关,客户端所有机器对外的IP地址都是相同,就会导致客户端A和客户端B的连接A比B的时间戳大,便会丢弃B的SYN包。

七、tcp_tw_reus默认为什么不是开启的?

八、正常挥手过程中,处于TIME_WAIT状态的连接收到相同四元组的SYN会怎么处理?

如果处于 TIME_WAIT 状态的连接收到「合法的 SYN 」后,就会重用此四元组连接,跳过 2MSL 而转变为 SYN_RECV 状态,接着就能进行建立连接过程。
如果处于 TIME_WAIT 状态的连接收到「非法的 SYN 」后,就会再回复一个第四次挥手的 ACK 报文,客户端收到后,发现并不是自己期望收到确认号(ack num),就回 RST 报文给服务端。

九、如何使用UDP实现可靠传输?

基于UDP实现的可靠传输QUIC协议。
要给予UDP实现可靠传输就要在应用层上下功夫。首先在建立连接阶段确定连接ID,使用此ID可以实现迁移功能。在传输数据时Packet Number每个报文是独一无二的,严格递增,传输中有数据包丢失也不影响后续数据包的传输,从而解决了TCP接收窗口队头阻塞问题,后续重传丢失的数据包的Packet Number值也是一个比之前丢失的包id值大。TCP重传丢失报文的序列号是一样的会导致计算RTT时间不太准确。
所以,Packet Number 单调递增的两个好处:

  • 可以更加精确计算 RTT,没有 TCP 重传的歧义性问题;
  • 可以支持乱序确认,防止因为丢包重传将当前窗口阻塞在原地,而 TCP 必须是顺序确认的,丢包时会导致窗口不滑动;

在这里插入图片描述
在这里插入图片描述
重传的数据包通过Offset保证数据的顺序性和可靠性。

十、UDP和TCP可以使用同一端口号吗?

可以的。
在这里插入图片描述
多个TCP服务进程可以绑定同一个端口号吗?
如果两个 TCP 服务进程同时绑定的 IP 地址和端口都相同,那么执行 bind() 时候就会出错,错误是“Address already in use”。

客户端的端口号可以重复使用吗?
TCP 连接是由四元组(源IP地址,源端口,目的IP地址,目的端口)唯一确认的,那么只要四元组中其中一个元素发生了变化,那么就表示不同的 TCP 连接的。所以如果客户端已使用端口 64992 与服务端 A 建立了连接,那么客户端要与服务端 B 建立连接,还是可以使用端口 64992 的,因为内核是通过四元祖信息来定位一个 TCP 连接的,并不会因为客户端的端口号相同,而导致连接冲突的问题。

多个客户端可以 bind 同一个端口吗?
要看多个客户端绑定的 IP + PORT 是否都相同,如果都是相同的,那么在执行 bind() 时候就会出错,错误是“Address already in use”。

如果一个绑定在 192.168.1.100:6666,一个绑定在 192.168.1.200:6666,因为 IP 不相同,所以执行 bind() 的时候,能正常绑定。

所以, 如果多个客户端同时绑定的 IP 地址和端口都是相同的,那么执行 bind() 时候就会出错,错误是“Address already in use”。

一般而言,客户端不建议使用 bind 函数,应该交由 connect 函数来选择端口会比较好,因为客户端的端口通常都没什么意义。

十一、服务端只bind了IP和port,没有进行listen这个socket监听连接,客户端向服务端发送socket数据,会怎样?

服务端如果只 bind 了 IP 地址和端口,而没有调用 listen 的话,然后客户端对服务端发起了连接建立,服务端会回 RST 报文。
参照源码TCP报文入口函数tcp_v4_rcv():
1)调用__inet_lookup_skb函数查找此报文的的socket;

int tcp_v4_rcv(struct sk_buff *skb)
{
 ...
  
 sk = __inet_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest);
 if (!sk)
  goto no_tcp_socket;
 ...
}

2)__inet_lookup_skb函数首先查找连接建立状态socket,找不到的话查找监听套接字接口;
在这里插入图片描述3)找不到监听改端口的socket,会RST;
在这里插入图片描述

十二、TCP四次挥手可以变为三次吗?

可以。
延迟确认机制。
在这里插入图片描述
最长/最短延时确认时间,开启/关闭TCP快速确认参数TCP_QUICKACK
在这里插入图片描述

// 1 表示开启 TCP_QUICKACK,即关闭 TCP 延迟确认机制
int value = 1;
setsockopt(socketfd, IPPROTO_TCP, TCP_QUICKACK, (char*)& value, sizeof(int));

十三‘、客户端收到第二次握手的ACK不是自己期望收到的,会怎么处理?

会回复RST。
三次握手是为了避免旧的历史连接被初始化。
在这里插入图片描述

就是这事,散会!

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

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

相关文章

Buffer Pool详解

文章目录一、简介二、缓存页三、Free链表四、Flush链表五、LRU链表六、脏页刷新七、多个Buffer pool八、Chunk单位一、简介 ​ mysql的数据都是存放在磁盘下的,为了加快cpu从磁盘i/o读取数据的效率,Innodb存储引擎在cpu和磁盘中间添加了一个缓冲区buffe…

web表格(详解)

目录 1.概述 2.表格的基本结构 3.表格的属性 4.单元格合并 1.概述 表格的基本语法结构&#xff1a; <table><tr><td>单元格内容</td>……</tr><tr><td>单元格内容</td>……</tr> </table> 其中< table>…

[附源码]SSM计算机毕业设计视屏网站论文JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

C++ Primer Plus第五版笔记(p51-100)

45 46 常量指针必须初始化 47 一条语句可以定义出不同类型的变量 int i10, *p&i,&r i; 48 应该是int p 而不是int p 49 **表示指向指针的指针 p52 50 指针是对象&#xff0c;所以存在对于指针的引用 int *p; int *&rp; 51 在默认状态下 &#xff0c;const对象只…

【教材】2022/11/27[指针] 指针与函数基础

程序&#xff1a;求10个数的最大数 1、定义指向函数的指针变量调用函数的方法 一般定义形式为&#xff1a;类型名 &#xff08;*指针变量名)()&#xff1b; #include<stdio.h> int main() {int i, m, a[10], max(int* p);int (*f)();for (i 0; i < 10; i)scanf_s(&q…

day7【代码随想录】移除链表元素

文章目录一、链表定义二、移除链表元素&#xff08;力扣203&#xff09;1、直接使用原来的链表来进行删除操作2、设置一个虚拟头结点在进行删除操作三、删除链表中的节点&#xff08;力扣237&#xff09;一、链表定义 public class ListNode {// 结点的值int val;// 下一个结点…

如何安装Jmeter监控服务器资源插件(JMeterPlugins + ServerAgent 方法二)?

一、服务器端插件 1、下载链接:https://pan.baidu.com/s/1Is1kuC656cB0mC4vOLHyhw?pwd12f1 提取码:12f1 &#xff08;或者这个下载服务器插件&#xff1a;ServerAgent 下载地址&#xff1a;https://github.com/undera/perfmon-agent&#xff09; 2、服务器端插件 将下载的Se…

Redis最全详解(一)——基础介绍

Redis介绍 redis是基于内存可持久化的日志型、Key-Value数据库。redis安装在磁盘&#xff0c;但是数据存储在内存。非关系型数据库NoSql。开源免费&#xff0c;遵守BSD协议&#xff0c;不用关注版权问题。 redis作者github&#xff1a;github.com/antirez redis是一种基于键…

【数字信号去噪】小波阙值数字信号去噪和求信噪比【含Matlab源码 2191期】

⛄一、小波阈值法去噪概述 电能质量扰动信号的噪声大多以高斯白噪声的形式存在&#xff0c;利用小波变换对信号进行多分辨率分解&#xff0c;由于小波变换具有去除数据相关性的特点&#xff0c;故可以将有用信号与噪声的能量分离开来。信号中有效的信息主要集中在较大的小波系…

[阶段4 企业开发进阶] 2. Redis--实战篇

文章目录实战篇1 短信登录1.1 导入项目导入SQL有关当前模型导入后端项目导入前端工程运行前端项目1.2 基于Session实现登录流程1.3 实现发送短信验证码功能1.4 实现登录校验拦截器1.5 隐藏用户敏感信息1.6 session共享问题实战篇 1 短信登录 1.1 导入项目 导入SQL 有关当前模…

多监控系统产生的告警如何高效管理 - 运维事件中心

随着互联网服务深入千行百业&#xff0c;数字化成为企业和机构为用户提供服务的重要形式。在企业的IT基础架构趋于复杂化的过程中&#xff0c;运维管理工作的技术性也有了更高的要求。如果针对相关的故障&#xff0c;企业无法做到及时的发现和响应&#xff0c;将会延长上层业务…

ElasticSearch中基础API操作

1:首先我们需要连接ElasticSearch客户端&#xff0c;需要一个连接操作&#xff1a; RestHighLevelClient package com.atguigu.es.test;import org.apache.http.HttpHost; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient;…

分布式全局唯一ID生成方案(附源码)

1、概述 ID&#xff0c;全称Identifier&#xff0c;中文翻译为标识符&#xff0c;是用来唯一标识对象或记录的符号。比如我们每个人都有自己的身份证号&#xff0c;这个就是我们的标识符&#xff0c;有了这个唯一标识&#xff0c;就能快速识别出每一个人。 在计算机世界里&…

客快物流大数据项目(八十八):ClickHouse快速入门

文章目录 ClickHouse快速入门 一、​​​​​​​​​​​​​​安装ClickHouse&#xff08;单机&#xff09; 1、安装yum-utils工具包 2、添加ClickHouse的yum源 3、安装ClickHouse的服务端和客户端 4、关于安装的说明 5、查看ClickHouse的版本信息 二、在命令行中操作…

【深度思考】5年开发经验,不知道git rebase,是否应该被嘲笑?

最近逛脉脉&#xff0c;发现了一个热度挺高的帖子&#xff0c;一位同学发帖说&#xff1a;同事5年经验&#xff0c;竟然不知道git rebase&#xff0c;真牛批 ☆ 今天咱们不讨论git rebase是干什么用的&#xff0c;因为讨论半天可能三两句话就说出来了&#xff0c;实在没有意思&…

Linux的进程互调技术(多语言互调)

Linux的进程互调技术(多语言互调) 文章目录Linux的进程互调技术(多语言互调)1.函数与进程之间的相似性2.多语言程序互调技术1.函数与进程之间的相似性 如果你学过C语言&#xff0c;你应该有以下认识&#xff1a; 一个C程序由很多函数组成&#xff0c;一个函数可以调用另一个函数…

STC 51单片机42——汇编 定时器 舵机

ORG 0000H HighH EQU 30H; 定义变量&#xff0c;高电平高八位 TimerH EQU 31H; 定义变量&#xff0c;高电平高八位定时值 TimerL EQU 32H; 定义变量&#xff0c;高电平低八位定时值 Right BIT P2.0 ; 右转 Left BIT P2.1 ; 左转 N…

IDEA搭建SSM框架【配置类、新手向】

以下操作基于2020.3企业版 1.创建Java Enterprise项目 直接默认即可 输入项目相关信息 点击完成后&#xff0c;得到以下目录结构 2.搭建项目目录结构 java目录下 controller&#xff1a;实现控制转发&#xff0c;基本参数校验&#xff0c;不复杂的简单业务处理 config&#x…

SpringBoot实现多数据源(一)【普通版切换】

在实际开发中&#xff0c;经常可能遇到在一个应用中可能需要访问多个数据库的情况。以下是两种典型场景 业务复杂&#xff08;数据量大&#xff09; 数据分布在不同的数据库中&#xff0c;数据库拆了&#xff0c;应用没拆。一个公司多个子项目&#xff0c;各用各的数据库&#…

Springboot——拦截器

目录 一、拦截器概念 二、拦截器的使用 2.1 拦截器的创建&#xff08;preHandle实用性最强&#xff09; 2.2 将拦截器添加到容器当中 三、拦截器参数 3.1 获取请求头 request.getHeader 3.2 Object handler 是什么参数 3.3 ModelAndView modelAndView 3.4 Exception ex 3.…