TCP问题总结

三次握手

TCP三次握手四次挥手过程

在这里插入图片描述

ACK数据包消耗TCP的序列号吗

单纯的ACK包不消耗,因为如果消耗序列号,那么对端也需要对这个ACK包进行确认,那么网络中就全是ACK了
如果是捎带应答,psh包和ACK包在一起,就会消耗序列号

TCP三次握手可以携带应用层数据吗

  • 前两次不可以,因为此时客户端服务端都没有进入连接状态,第三次可以携带数据,但是很少有这么做的。
  • 如果前两次可以携带数据,那么攻击者就可以对服务器进行连接在第一次握手时,发送大量的数据,完全不管服务器能否接收
  • TCP的拥塞控制,会在连接初始阶段进行慢启动,试探网络状况,因此一般都不会在第三次握手携带数据

服务端不进行accept,最多可以三次握手完成多少次连接

在这里插入图片描述
在这里插入图片描述

  • 三次握手都是由内核完成,而accept是从已完成连接队列中获取连接,如果服务端一直不accept,那么能完成的连接总数就是backlog + 1,已完成连接队列的容量

tcp三次握手的序号是从0开始的吗

  • 都不一定是从0开始的,而是一个32位计数器,动态变化的
  • 序号的作用:为了防止在网络中被延迟的分组后又被传送到,从而导致连接一方做出错误的解释,
  • 如果从0开始,当一个连接完成后,序号从0开始,第一个消息发送序号是1,此时1号包在网络中阻塞了,同时服务端或者客户端掉线了断开了,之后重新连接重新开始通信后,之前发送的1号包又重新到达,发生错误

tcp最多创建多少连接

  • 即一个进程最多打开多少文件描述符
  • 通过ulimit -a 查看open files,默认是65535或者1024 需要去掉标准输入标准输出标准错误+监听套接字
  • ulimit -n nums 进行修改为nums个

tcp为什么需要MSS

tcp规定一次性最多发送的数据大小就是MSS字节,以客户端和服务端的最小的那个MSS为准

  1. 为了防止数据包过大,因为ip不可靠,防止重传大数据包
  2. MSS + tcp头部+ ip头部<=MTU, MTU是最大传输单元,ip一个数据帧的最大值
  3. 数据小于MSS ip就一定不会分片,如果分片了,丢失的

四次挥手

服务端出现大量的CLOSE_WAIT状态

  • CLOSE_WAIT状态是被动断开方接受到对方的fin报文后发出ack后的状态,服务端发送完所有数据后,发送fin包后变成LAST_ACK状态(调用close())
    1. 可能是服务端的线程阻塞无法调用close
    2. 在close之前有大量消耗时间的逻辑

其他

SYN报文什么时候会被丢弃

可能性1. TCP的半连接队列已满(半连接队列和全连接队列也叫未完成连接队列和已完成连接队列)
详细原因:
- 服务端收到客户端的SYN请求后,内核将连接存储到半连接队列,并向客户端相应SYN+ACK
- 客户端返回ACK后,将连接加入到全连接队列
- 服务端调用accept后,将连接从全连接队列中取出
- 当半连接队列满了,那么SYN就会丢弃
解决办法:
+ 增大半连接队列以及全连接队列
+ 开启tcp_syncookies功能
在第二次握手时,向对方发送一个cookies,对方回复ack后校验cookies来看连接是否合法
让连接在第二次握手的时候不进入半连接队列,通过校验cookies后直接进入全连接队列
/proc/sys/net/ipv4/tcp_syncookies 0是关闭 1是当半连接队列满时启用 2是无条件开启
+ 减少SYN+ACK重传次数
syn泛洪攻击,攻击者发送SYN后不发送ACK,让这个连接一直占用半连接队列,服务端默认的超时重传5次ACK+SYN,这个时间内连接一直占用半连接队列,通过设置重传次数减少占用时间
+ 检查代码为什么不调用accept,当全连接队列满了之后,完成三次握手的连接也会继续占用半连接队列,因此也可以通过

可能性 2. 开启tcp_tw_recycle参数,且在NAt环境下,tcp_tw_recycle+NAT是不安全的

  1. linux下TIME_WAIT时间是60s,即使主动断开连接的那个进程退出了,被占用的那个端口还在被占用。
  2. 客户端连接可以不通过自己bind,通过connect函数,操作系统分配端口,一般可分配的端口是32768-61000,如果是客户端发起了大量连接,同时这些连接都主动断开,如果客户端此时没有端口了,但是还想发起连接咋办,tcp_tw_recycle参数就起作用了
    1. tcp_tw_recycle可以让客户端的time_wait快速回收,还有一个tcp_tw_reuse选项,这个选项开启的话,是如果客户端主动发起连接(connect)发现端口是被相同的四元组占用,且处于timewait状态,time_wait状态持续超过1s就会重新启用这个连接,开启这两个选项需要开启时间戳选项
    2. 私有ip是无法直接访问互联网的,私网ip是为了解决ipv4地址枯竭问题的,不同的真实client经过同一个NAT服务器转变为同一个公网ip再去访问互联网,在服务端看来这都是和同一个host打交道,但是不同的真实client有自己的时间戳,无法保证时间戳严格递增,那么服务器的PAWS机制(防止序号回环的机制)被触发后就会丢弃时间戳不符合的数据包,例如当先到了一个时间戳1-10的数据包,后来又到了个8的时间戳,此时服务端就会丢弃此数据包
      在这里插入图片描述

什么是确认应答机制

  • 本质是对序列号的确认,tcp对每个字节的数据都进行了编号,数据接收到1~1000,ack回复确认1001,告诉对方我需要1001的数据,

什么是快重传

  • 区别于拥塞控制的快速重传
  • 快重传是为了在没有触发超时重传的时候,就立即重传丢失的数据,本质是为了提升传输效率
    发送方接收到三次同样的确认之后,会立即重传丢失的报文,
    那么为什么是三次呢?

如果发送发已经发送了数据包,N-1,N,N+1,N+2
此时收到一次ack(N),可以认为是N还未到
收到第二次ack(N),可以认为是N+1先于N到达,此时可能是网络乱序
收到第三次ack(N),此时可能是N+2先于N到达,或者是N丢包了,此时后者的概率会比较的大,所以此时触发快重传是合理的

快重传的漏洞就是,不知道是重传一个N,还是重传后面的多个包比如:

  1. 发送方发送了1-10号包,此时2,3,4都丢失了
  2. 此时收到三次ack(2),但是快重传只会重传2,不能一次重传2-4
  3. 通过SACK和DSACK解决

SACK 选择性确认

在三次握手时协商双方是否都支持SACK,协商成功后在tcp头部添加SACK字段,将已经收到的数据信息发送给对方

拔掉网线后tcp连接还在吗

  • tcp连接并不是实体的,是通信双方各自维护的一个struct socket,包含对方的ip。端口等信息,拔掉网线之后(也可以是中间的路由器断掉),这个结构体依然存在,因此可以认为:
  1. 如果有数据传输,触发超时重传上限
    1. 如果超时重传上限之前,网线重连了,对程序员是无感的
    2. 触发上限了, tcp通知上层应用程序连接断开,程序员根据通知继续后续的工作
  2. 如果没有超时重传,触发心跳机制
    1. tcp keepalive机制,当空闲超过两个小时,每隔75s发送一次探测报文,探测9次若9次都没有收到ack,则认为连接断开了,这个机制需要设置tcp keepalive
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值