讲一下OSI七层模型?
OSI七层模型最终并没有成为广为使用的标准模型。可能是OSI的专家缺乏实际经验,OSI标准制定周期过长,按OSI标准生产的设备无法及时进入市场,OSI模型设计的并不合理,一些功能在多层中重复出现等原因造成的。除了标准的OSI七层模型以外,常见的网络层次划分还有TCP/IP四层协议以及TCP/IP五层协议,它们之间的对应关系如下图所示:
网络协议有几层?分别是什么?
为什么要将数据切片?
软件是属于应用层上的。
消息在进入传输层时使用的是传输层上的 TCP 协议.
消息在进入传输层(TCP)时会被切片为一个个数据包。这个数据包的长度是MSS。
可以把网络比喻为一个水管,是有一定的粗细的,这个粗细由网络接口层(数据链路层)提供给网络层,一般认为是的MTU(1500),直接传入整个消息,会超过水管的最大承受范围,那么,就需要进行切片,成为一个个数据包,这样消息才能正常通过“水管”。
MTU 和 MSS 有什么区别
MTU: Maximum Transmit Unit,最大传输单元。 由网络接口层(数据链路层)提供给网络层最大一次传输数据的大小;一般 MTU=1500 Byte。
假设IP层有 <= 1500 byte 需要发送,只需要一个 IP 包就可以完成发送任务;假设 IP 层有> 1500 byte 数据需要发送,需要分片才能完成发送,分片后的 IP Header ID 相同。
MSS:Maximum Segment Size。TCP 提交给 IP 层最大分段大小,不包含 TCP Header 和 TCP Option,只包含 TCP Payload ,MSS 是 TCP 用来限制应用层最大的发送字节数。
假设 MTU= 1500 byte,那么MSS = 1500- 20(IP Header) -20 (TCP Header) = 1460 byte,如果应用层有2000 byte发送,那么需要两个切片才可以完成发送,第一个 TCP 切片 = 1460,第二个 TCP 切片 = 540。
什么是粘包?
在组包过程中,把上一个包的内容与下一个包里的粘在了一起被错误地当成了一个数据包解析了出来。这就是所谓的粘包。
为什么会出现粘包?
字节流可以理解为一个双向的通道里流淌的数据,这个数据其实就是我们常说的二进制数据,简单来说就是一大堆 01 串。这些 01 串之间没有任何边界。
应用层传到 TCP 协议的数据,不是以消息报为单位向目的主机发送,而是以字节流的方式发送到下游,这些数据可能被切割和组装成各种数据包,接收端收到这些数据包后没有正确还原原来的消息,因此出现粘包现象。
讲一下什么是TCP协议?
TCP,Transmission Control Protocol。传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议。
怎么处理粘包?
粘包出现的根本原因是不确定消息的边界。接收端在面对"无边无际"的二进制流的时候,根本不知道收了多少 01 才算一个消息。一不小心拿多了就说是粘包。其实粘包根本不是 TCP 的问题,是使用者对于 TCP 的理解有误导致的一个问题。
只要在发送端每次发送消息的时候给消息带上识别消息边界的信息,接收端就可以根据这些信息识别出消息的边界,从而区分出每个消息。
常见的方法有
加入特殊标志
可以通过特殊的标志作为头尾,比如当收到了0xfffffe或者回车符,则认为收到了新消息的头,此时继续取数据,直到收到下一个头标志0xfffffe或者尾部标记,才认为是一个完整消息。类似的像 HTTP 协议里当使用chunked 编码传输时,使用若干个 chunk 组成消息,最后由一个标明长度为 0 的 chunk 结束。
加入消息长度信息
这个一般配合上面的特殊标志一起使用,在收到头标志时,里面还可以带上消息长度,以此表明在这之后多少 byte 都是属于这个消息的。如果在这之后正好有符合长度的 byte,则取走,作为一个完整消息给应用层使用。在实际场景中,HTTP 中的Content-Length就起了类似的作用,当接收端收到的消息长度小于 Content-Length 时,说明还有些消息没收到。那接收端会一直等,直到拿够了消息或超时。
可能这时候会有朋友会问,采用0xfffffe标志位,用来标志一个数据包的开头,你就不怕你发的某个数据里正好有这个内容吗?
是的,怕,所以一般除了这个标志位,发送端在发送时还会加入各种校验字段(校验和或者对整段完整数据进行CRC之后获得的数据)放在标志位后面,在接收端拿到整段数据后校验下确保它就是发送端发来的完整数据。
UDP 会粘包吗?
不会有粘包问题。
讲一下什么是UDP协议?
UDP,User Datagram Protocol。用户数据包协议,是面向无连接,不可靠的,基于数据报的传输层通信协议。