TCP/IP协议

传输层

TCP协议

报头与有效载荷如何分离?如何将有效载荷交付给上层?

固定长度+自描述字段(4位首部长度)

根据目的端口号交付给相应的上层协议或应用程序。

TCP协议格式

4位首部长度:头部长度,单位4字节,范围就是[0,60],如果有选项,头部长度-20字节就是选项大小

TCP三次握手和四次挥手

三次握手建立连接

为什么是三次握手?

1、三次握手可靠验证了全双工

2、奇数次握手,把失败成本嫁接给了客户端

client在第三次ACK之后,就认为连接已经建立完成了,所以资源都准备就绪了,失败成本就会在client端

细节:

1、三次握手和上层accept没有关系,都是操作系统自动完成

2、上层listen函数第二个参数backlog,backlog+1表示已经建立好连接的全连接队列最大长度

3、server端,不会长时间维护SYN_RECVD,被建立连接的一方,会把SYN_RECVD放入半连接队列,该队列中节点不会长时间维护

4、主动断开连接的一方,在四次挥手之后,会进入TIME_WAIT状态,等待若干时长后自动释放

TIME_WAIT等待多少时间?为什么?

1)一般是60~120秒

2)让双方历史通信数据消散

3)让双方在四次挥手时,有更好的容错性

出现bind错误的原因是什么???

连接没有彻底断开,ip和端口号还在继续使用

解决办法:

注:

逻辑上两台主机之间在传输层之间直接进行三次握手和四次挥手

但是实际上是需要网络层和数据链路层的参与

TCP可靠性

1、校验和

发送端填充, CRC校验. 接收端校验不通过, 则认为数据有问题. 此处的检验和不光包含TCP首部, 也 包含TCP数据部分

2、序列号

保证数据在放送时,接收方接收到的时的正确顺序

3、确认应答

ACK,保证对方主机收到我发出去的数据,收到ACK之后再发下一个数据段

4、超时重传

再特定时间间隔内,发出去的数据没有收到ACK,就会重新发

5、连接管理

三次握手和四次挥手

6、流量控制

如果发送缓冲区数据发送过快,立刻把对方的接收缓冲区打满,如果再继续发送,就可能会导致丢包问题

滑动窗口

一般使用滑动窗口来实现流量控制

窗口大小是由对方接收缓冲区决定的

怎么知道对方的接收缓冲区大小的?

在三次握手之后,双方交换了报文,已经具有协商沟通的能力

双指针来控制窗口大小

确认序号:确认序号xxx,表示xxx之前的都接收到了(允许少量ACK丢失)

7、拥塞控制

如果在网络情况拥堵的的情况下,一开始就发送大量数据,可能会导致网络直接崩掉

拥塞控制也就是**"慢启动"**,先发少量数据,之后指数增长数据量

TCP提高性能机制

1、滑动窗口

2、快重传

如下图所示为快重传,当收到三次重复的确认应答,主机A就会直接重发1---1000数据段的内容

3、延迟应答

一次传输的数据越大效率越高

窗口越大,传出数据越大

怎样让窗口越大?

可以让对方read和recv尽快把缓冲区中的数据读走

4、捎带应答

把数据和ACK应答一起发送,提高效率

面向字节流

创建TCP的socket时,创建了一个接收缓冲区和一个发送缓冲区

一个连接既可以写又可以读,这种被称为全双工

接收方读缓冲区直接冲对方写缓冲区中读,序列号确定了读的顺序,所以确定了TCP是面向字节流的

用户对报文一个个处理,将字节流变成一个个请求

但是这里就会出现一个问题,怎么保证拿到的就是一个完整的报文???

粘包问题

当从缓存区拿到的不是一个完整的报文,就会出现粘包问题

解决办法:定协议(Decode 和 Encode)

明确报文与报文之间的边界

1、使用定长报文

2、使用特殊字符

3、定长报头+自描述字段

4、定长报头+特殊字符

TCP异常情况

1、进程终止:连接正常断开

2、重启:关闭所有进程,连接断开

3、机械断电:正常四次 挥手,保活机制

网络层

IP协议

如何将报头与有效载荷分离?

固定长度+自描述字段

如何将有效载荷交付给上层?

8位协议

4位版本号(version): 指定IP协议的版本, 对于IPv4来说, 就是4.

4位头部长度(header length): IP头部的长度是多少个32bit, 也就是 length * 4 的字节数. 4bit表示最大 的数字是15, 因此IP头部最大长度是60字节.

8位服务类型(Type Of Service): 3位优先权字段(已经弃用), 4位TOS字段, 和1位保留字段(必须置为0). 4位 TOS分别表示: 最小延时, 最大吞吐量, 最高可靠性, 最小成本. 这四者相互冲突, 只能选择一个. 对于 ssh/telnet这样的应用程序, 最小延时比较重要; 对于ftp这样的程序, 最大吞吐量比较重要

IP分片

在数据链路层,要求上层不能发过大的报文,所以会产生IP分片(TCP流量控制也是为了不发过大的报文到下层)

16位标识(id): 唯一的标识主机发送的报文. 如果IP报文在数据链路层被分片了, 那么每一个片里面的这个 id都是相同的.

3位标志字段: 第一位保留(保留的意思是现在不用, 但是还没想好说不定以后要用到). 第二位置为1表示禁 止分片, 这时候如果报文长度超过MTU, IP模块就会丢弃报文. 第三位表示"更多分片", 如果分片了的话, 最后一个分片置为1, 其他是0. 类似于一个结束标记.

13位分片偏移(framegament offset): 是分片相对于原始IP报文开始处的偏移. 其实就是在表示当前分片 在原报文中处在哪个位置. 实际偏移的字节数是这个值 * 8 得到的. 因此, 除了最后一个报文之外, 其他报 文的长度必须是8的整数倍(否则报文就不连续了).

如上图所示,IP分片之后,每个分片都要有报头

细节问题:

如何检查是否有片丢失?

1)前面的片都可以用片偏移来判断是否丢失

2)最后一个可以通过三位标志字段最后一位来判断,因为只有最后一个片是0

如何组装分片?

片偏移排序

为什么不建议分片?

因为任何一个片丢失,都需要重新发送,增加了丢包的概率

IP协议的本质就是提供一种能力,将数据从A主机跨网络传到B主机

通过路由器进行下一跳到另一个路由器,直到到达目的主机所在的路由器网络

网络中那么多路由器,怎么直到要怎么下一个路由器的??

每个路由器节点都维护一张路由表,查表就知道目标IP地址该怎么走

路由器:不仅可以进行ip地址转发,还可以构建子网

特殊IP地址

主机IP地址全设为0,表示的就是该局域网

主机IP地址全设为1,表示广播,向该局域网内所有主机发送数据

数据链路层

IP协议找到目的主机所在的局域网,这里就需要在局域网找具体的物理地址

为什么IP协议已经找了局域网,为什么不直接找目的IP地址??

因为IP地址是可以重复使用的

MAC地址

表示唯一的地址

arp协议

在一个局域网中,主机A要给主机B发送消息,就要知道主机B的MAC地址

1、主机A以广播方式向所有主机发送arp请求(如果arp表中没有主机B的MAC地址就会广播)

2、所有主机接受请求后舍弃,只有主机B才会接受,并且应答,应答中就带有自己的MAC地址

因为在A主机广播时就带有自己的MAC地址,所以B主机就能够直接给主机A发送arp应答

arp协议属于数据链路层,但是是在mac地址之上的

相关推荐
桌面运维家2 小时前
Windows/Linux云桌面:高校VDisk方案部署指南
linux·运维·windows
Du_chong_huan2 小时前
1.7 计算机网络和因特网的历史 | 《计算机网络:自顶向下方法》精读版
运维·服务器·网络
ZZZKKKRTSAE2 小时前
rhel9快速上手Docker
运维·docker·容器
筱顾大牛2 小时前
Docker安装教程(加汉化!超详细!!!)
运维·docker·容器
没头脑的男大2 小时前
关于tailscale和ssh那些事儿
运维·服务器·ssh
竹之却2 小时前
OpenClaw 接入QQ-Bot + 接入Feishu(飞书)
运维·服务器·飞书·openclaw·qq-bot·opencalw接入qq+飞书
九成宫2 小时前
安装和配置Docker教程(装在其他盘)
运维·docker·容器
野犬寒鸦2 小时前
JVM垃圾回收机制面试常问问题及详解
java·服务器·开发语言·jvm·后端·算法·面试
马士兵教育2 小时前
RocketMQ如何进行性能调优?
服务器·windows·rocketmq