网络原理-TCP/IP

发布于:2025-08-03 ⋅ 阅读:(11) ⋅ 点赞:(0)

目录

1.应用层

2.传输层

2.1端口号

2.2UDP协议

2.3TCP协议

2.3.1确认应答

2.3.2超时重传

2.3.4连接管理

2.3.5滑动窗口

2.3.6流量控制

2.3.7拥塞控制

2.3.8延迟应答

2.3.9捎带应答

2.3.10面向字节流和粘包问题

2.3.11异常情况


1.应用层

应用层主要是程序员和应用程序关注的层,应用层的协议主要约定了如何组织数据,以及要传输哪些数据,数据的格式等等,我们可以借用XML,或者JSON这两种语言,帮助我们制定好数据交换的格式,目前先简单了解,后面详细介绍。

2.传输层

传输层主要负责端到端的传输控制,主要负责确定传输双方的端口号,也就是哪台主机的哪个进程发送给哪台主机的哪个进程。端口号是用来标识主机上的进程的。一般用16bit位表示,大小为0~65525。

2.1端口号

端口号标识了一个主机上进行通信的不同进程。

端口号范围:

1.有些知名端口号已被占用,范围在0~1023,比如HTTP占用了80端口号等等,他们的端口号是固定的,所以最好不使用该范围的端口号来绑定进程。

2.我们可以使用1024~65535的端口号来绑定进程,由操作系统可以来为进程动态分配。

两个问题:

1.⼀个进程是否可以bind多个端⼝号?

  可以,只要端口号绑定的进程唯一即可。
2.⼀个端⼝号是否可以被多个进程bind?

  不可以,端口号是用来标识通信进程的,一个端口号绑定多个进程,会产生冲突。

五元组:

在TCP/IP中,用五元组来表示一个通信:

1.源IP地址:发送方主机IP

2.目的IP地址:接收方主机IP

3.协议号:通信双方约定的数据格式。

4.源端口号:标识发送方主机上的通信进程

5.目的端口号:标识接收方主机上的通信进程

2.2UDP协议

UDP协议是一种无连接,只需要知道双方的端口号和IP地址,不需要建立连接,是一种不可靠的传输,不可靠的含义就是发送方只负责发送,不关心对方是否接收到,并且是一种面向数据报发送的,一次发送完数据,不能分多次发送。

UDP协议端格式:

UDP长度:表示整个数据报的长度,包括UDP首部,一共16位,最大为64KB。

UDP校验和:根据校验算法生成的校验和。(接收方如果根据校验和计算出数据传输有错,则直接丢弃)

2.3TCP协议

TCP全称为 "传输控制协议(Transmission Control Protocol"). TCP协议是一种有连接的传输,并且是一种可靠传输,面向字节流传输。

TCP协议段格式:

1.源端口号和目的端口号分别代表发送方的进程和接收方的进程。

2.序号和确认序号是TCP可靠传输用来组织应答的。

3.首部长度用4位表示,表示TCP头部有多少个4byte,TCP首部最大长度为15*4=60byte。

4.6个标志位,

URG: 紧急指针是否有效

ACK: 确认号是否有效

PSH: 提⽰接收端应⽤程序⽴刻从TCP缓冲区把数据读⾛

RST: 对⽅要求重新建⽴连接; 我们把携带RST标识的称为复位报⽂段

SYN: 请求建⽴连接; 我们把携带SYN标识的称为同步报⽂段

FIN: 通知对⽅, 本端要关闭了, 我们称携带FIN标识的为结束报⽂段
5.窗口大小:滑动窗口的大小

6.校验和:根据CRC计算出的校验和,用于验证数据传输是否出错。

7.紧急指针:告诉接收方数据中哪些位置需要先处理。

TCP通过以下这些机制,保证了可靠传输

2.3.1确认应答

确认应答是为了保证,传输双方对发送的数据报进行标识和应答操作,保证每个数据报成功发送并且对相应的数据报应答。

TCP将每个字节的数据进行编号,也就是序列号,比如每1000个字节为一个数据报,那么在发送第一个数据报时,也就是1~1000字节,会将TCP段中的序号填充为1000,接收方收到时,会进行应答,也就是将发送方的序号加1,填充到确认序号中,表示下一个接收的数据从1001开始,这就完成了一次确认应答。

应答:只是传输层接收方给发送方的一个回复,一个标记,并无真实结果。

响应:是应用层根据请求计算出的结果。

2.3.2超时重传

为了防止数据包在网络运输过程中发生丢包,需要重新发送采用的重传机制。

分为两种情况:

1.发送超时:

主机A在发送数据包中,中途丢包了,没有发送到主机B,在特定的时间间隔后,主机A还没接收到该数据包的应答,那么就会重新再发送一次。

2.接收方收到了数据包,但应答超时

主机B收到了该数据包,但是应答在传输时在网络中丢包了,特定时间间隔后,主机A又对该数据包重传,主机B又收到了相同的数据包(根据序号判断),那么会舍弃当前包,因为缓存区中已有该包的内容,然后再进行应答即可。

2.3.4连接管理

由于TCP通信是需要建立连接的,因此需要对连接进行管理,分别为建立连接,和关闭连接。

1.建立连接:三次握手

作用:在通信双方初次建立连接时,确认双方的收发能力。

步骤:

1.主机A给接收方发送一个SYN建立连接请求,将SYN字段置为1,生成一个随机数填充到序号中

2.主机B接收到主机A发来的SYN请求后,将序号加1的结果填充到确认序号,并且把ACK置为1,表示要进行应答操作,同时也生成一个随机数填充到序号中,并且把SYN置为1,表示发送一个SYN建立连接请求(主要是为了验证发送方是否有应答能力)

3.主机A收到了主机B发来的ACK+SYN应答后,知道了主机B有接收应答能力,并且收到了主机B发来的SYN请求,在发来的序号+1填充到确认序号中,把ACK置为1,表示应答

4.主机B收到了主机A的ACK应答,知道了主机A也有接收应答能力,自此建立连接成功,双方都有收发数据能力。

相关面试题:

TCP三次握手可以变成两次或者四次吗?

两次不可以,因为如果最后发送方不回应应答,那么接收方不知道发送方是否有接收能力。

四次可以,但是没必要,也就是中间把ACK和SYN分别发送。

2.关闭连接:四次挥手

作用:确认安全的断开连接。

步骤:

1.主动方主动发送FIN关闭连接请求,将FIN字段置为1.

2.被动方收到FIN请求后,操作系统自动回复一个ACK应答,并且准备发送完最后需要发送的数据,以及做一些关闭连接的准备工作。

3.被动方主动调用close方法关闭一些资源,并且发送一个FIN关闭连接请求给主动方。

4.主动方收到FIN请求,发送ACK确认应答,关闭资源,被动方收到应答后,关闭连接成功。
 

面试题:

TCP四次挥手能不能变成三次挥手:

大概率不能,因为被动方的ACK和FIN请求不能同时发送,一是因为发起者不同,ACK是操作系统层面,FIN请求是应用层层面,二是发起时机不同,ACK需即使确认应答,而FIN需要回收一些资源后再发送。

如果在某些不需要回收资源的场景下,ACK和FIN可都由内核态同时触发。

2.3.5滑动窗口

滑动窗机是为了提升效率提出的,如果每发送一个数据包,只有等到应答后才发送下一个,那么效率就太低了,于是引出了滑动窗口。

滑动窗口由数据段组成,大小就是能装下数据段的个数,假如每个数据段有1000字节,滑动窗口中的数据是不需要等待应答就可以发送的,每接收相应的应答,那么窗口就可以往后滑动,将剩下的数据段加进来。操作系统内核为了维护这个滑动窗⼝, 需要开辟 发送缓冲区 来记录当前还有哪些数据没有应答; 只有确认应答过的数据, 才能从缓冲区删掉;

无需一个一个等待应答后再发送,一次可以发送很多个数据段。

异常情况一:数据包已经抵达,但是ACK丢包了

确认序号为2001的丢失了,但是之后的应答没丢失,那么主机A就认为2001的数据包也收到了,就会将2001这个数据包移除缓冲区。

异常情况二:数据包丢失了

假设主机A同时发送1~4000的数据,在发送1001~2000这个数据包时丢包了,主机B一直没有接收到该数据包,那么就会每接收一个数据包就发送1001的确认应答,表示下一个数据包是1001开头,那么主机A在连续三次收到这个ACK后,就知道1001~2000这个数据包丢失了,就重传1001~2000这个数据包。

2.3.6流量控制

有了滑动窗口后,大大提高了效率,但是窗口的大小也不能无限的增大,接收方的缓冲区也是有大小限制的。

一般通过TCP段中的窗口大小来通知发送方当前接收方缓冲区能接收的最大数据包大小,通过ACK应答告诉发送方,如果接收端的缓冲区满了,就会将窗口设置为0,这时发送方不能再发送数据,但是需要定期发送⼀个窗⼝探测数据段, 使接收端把窗⼝⼤⼩告诉发送端.

TCP字段中的窗口大小也就是用来告诉发送方,接收方能接收的最大窗口大小,16位代表最大能接收65535个字节,但是TCP字段中的选项包含了一个窗口扩大因子M,实际窗口大小是窗⼝字段的值左移 M 位;

2.3.7拥塞控制

该机制是用于网络的畅通情况来决定滑动窗口大小,以防网络过于拥堵,而窗口大小太大发生严重拥塞。

滑动窗口大小是min(拥塞窗口,ACK应答包中的窗口大小)

假设拥塞门限为16

1.刚开始为慢启动,拥塞窗口大小为1

2.每收到一个ACK应答,拥塞窗口大小*=2,也就是指数型增长

3.当拥塞窗口大小达到拥塞门限大小时(不能超过拥塞门限),此时开始按照线性方式增长,也就是拥塞窗口大小递增。

4.当发送方收到3个重复的ACK后,此时网络拥堵导致丢包,将拥塞窗口大小置为1,拥塞门限为当前拥塞窗口大小一半,重复2~4步。

2.3.8延迟应答

每收到一个数据包就应答一次的话效率过于低效,我们可以设定指定接收多少个数据包再进行应答一次,或者指定多少延迟时间内再应答一次。

2.3.9捎带应答

在有些服务端中会出现一问一答,比如聊天室,我们在收到用户发来的消息时也需要回复,那么我们就可以将ACK应答和服务端的响应一起打包在一个数据包同时发送,这就是捎带应答。

2.3.10面向字节流和粘包问题

由于TCP是面向字节流的,在创建socket对象后,会在内核区创建发送缓冲区和接收缓冲区,在我们发送数据包时,会先写入发送缓冲区,等到接收一定数据后,再统一发送,接收缓冲区也是如此,在接收消息时放入接收缓冲区并不会马上读取,而是等待接收一定数量后读取,那么对应应用层而言,多条数据包的数据并不能划分开,无法知道每条消息的开头和结尾在哪,这就是粘包问题。

粘包问题解决办法:

1.为每个消息定义一个分隔符,用分隔符来区分消息。

2.在应用层协议为消息加一个长度字段,用来表示消息的长度,因为传输层向上层传输载荷时,该载荷的数据只和应用层有关。

对于UDP, 如果还没有上层交付数据, UDP的报⽂⻓度仍然在. 同时, UDP是⼀个⼀个把数据交付给⽤层. 就有很明确的数据边界.站在应⽤层的⻆度, 使⽤UDP的时候, 要么收到完整的UDP报⽂, 要么不收. 不会出现"半个"的情况.

2.3.11异常情况

1.进程崩溃:系统回收进程申请的资源,会自动调用close方法,触发FIN关闭连接请求,正常断开连接。

2.正常关机:和进程崩溃一样。

3.主机掉电或着掉网:

  1. 接收方断网:发送方持续收不到ACK应答,多次进行超时重传,最后在重新申请连接,失败后断开连接。
  2. 发送方断网:发送方定期检测接收方是否在线,也就是每隔一段时间发一个心跳包报文,如果接收方一直没有回应这个心跳包,那么就断开连接。

网站公告

今日签到

点亮在社区的每一天
去签到