【计算机网络 - 基础问题】每日 3 题(二十四)

news/2024/11/17 7:31:36/

✍个人博客:Pandaconda-CSDN博客
📣专栏地址:http://t.csdnimg.cn/fYaBd
📚专栏简介:在这个专栏中,我将会分享 C++ 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪
📝推荐参考地址:https://www.xiaolincoding.com/(这个大佬的专栏非常有用!)

70. 解释 TCP 为什么是流协议?怎么分割?

当用户消息通过 TCP 协议传输时,消息可能会被操作系统分组成多个的 TCP 报文,也就是一个完整的用户消息被拆分成多个 TCP 报文进行传输。

这时,接收方的程序如果不知道发送方发送的消息的长度,也就是不知道消息的边界时,是无法读出一个有效的用户消息的,因为用户消息被拆分成多个 TCP 报文后,并不能像 UDP 那样,一个 UDP 报文就能代表一个完整的用户消息。

举个实际的例子来说明。

发送方准备发送「Hi.」和「I am Xiaolin」这两个消息。

在发送端,当我们调用 send 函数完成数据“发送”以后,数据并没有被真正从网络上发送出去,只是从应用程序拷贝到了操作系统内核协议栈中。

至于什么时候真正被发送,取决于发送窗口、拥塞窗口以及当前发送缓冲区的大小等条件。也就是说,我们不能认为每次 send 调用发送的数据,都会作为一个整体完整地消息被发送出去。

如果我们考虑实际网络传输过程中的各种影响,假设发送端陆续调用 send 函数先后发送「Hi.」和「I am Xiaolin」报文,那么实际的发送很有可能是这几种情况。

第一种情况,这两个消息被分到同一个 TCP 报文,像这样:

在这里插入图片描述

第二种情况,「I am Xiaolin」的部分随「Hi」在一个 TCP 报文中发送出去,像这样:

在这里插入图片描述

第三种情况,「Hi.」的一部分随 TCP 报文被发送出去,另一部分和「I am Xiaolin」一起随另一个 TCP 报文发送出去,像这样。

在这里插入图片描述

类似的情况还能举例很多种,这里主要是想说明,我们不知道「Hi.」和「I am Xiaolin」这两个用户消息是如何进行 TCP 分组传输的。

因此,我们不能认为一个用户消息对应一个 TCP 报文,正因为这样,所以 TCP 是面向字节流的协议。

当两个消息的某个部分内容被分到同一个 TCP 报文时,就是我们常说的 TCP 粘包问题,这时接收方不知道消息的边界的话,是无法读出有效的消息。

要解决这个问题,要交给应用程序。

71. TCP 粘包问题

  1. 固定长度

指定固定的长度,实现起来简单方便,但是可能会浪费内存资源。

  1. 特殊分隔符

我们可以在两个用户消息之间插入一个特殊的字符串,这样接收方在接收数据时,读到了这个特殊字符,就把认为已经读完一个完整的消息。

HTTP 是一个非常好的例子,通过 \r\n 来进行分隔。

在这里插入图片描述

HTTP 通过设置回车符、换行符作为 HTTP 报文协议的边界。

有一点要注意,这个作为边界点的特殊字符,如果刚好消息内容里有这个特殊字符,我们要对这个字符转义,避免被接收方当作消息的边界点而解析到无效的数据。

  1. 自定义消息结构

我们可以自定义一个消息结构,由包头和数据组成,其中包头包是固定大小的,而且包头里有一个字段来说明紧随其后的数据有多大。

比如这个消息结构体,首先 4 个字节大小的变量来表示数据长度,真正的数据则在后面。

struct { u_int32_t message_length; char message_data[]; 
} message;

当接收方接收到包头的大小(比如 4 个字节)后,就解析包头的内容,于是就可以知道数据的长度,然后接下来就继续读取数据,直到读满数据的长度,就可以组装成一个完整到用户消息来处理了。

72. protobuf 了解吗?

Protobuf 是用于数据序列化和反序列化的格式,类似于 JSON。但它们有以下几点区别:

  • 数据大小:Protobuf 是一种二进制格式,相对于 JSON 来说,数据大小更小,序列化和反序列化的效率更高,因此在网络传输和存储方面具有一定的优势。
  • 性能:由于 Protobuf 是二进制格式,相对于 JSON 来说,解析速度更快,占用的 CPU 和内存资源更少,因此在高并发场景下,性能更优。
  • 可读性:JSON 是一种文本格式,可读性更好,易于调试和排查问题。而 Protobuf 是一种二进制格式,可读性较差。

Protobuf 适用于高性能、大数据量、高并发等场景,而 JSON 适用于数据交换、易读性要求高的场景。


http://www.ppmy.cn/news/1531675.html

相关文章

《迁移学习》—— 将 ResNet18 模型迁移到食物分类项目中

文章目录 一、迁移学习的简单介绍1.迁移学习是什么?2.迁移学习的步骤 二、数据集介绍三、代码实现1. 步骤2.所用到方法介绍的文章链接3. 完整代码 一、迁移学习的简单介绍 1.迁移学习是什么? 迁移学习是指利用已经训练好的模型,在新的任务上…

QtCreator的界面

编辑 advanced Auto-indent Selection:自动缩进选择。将所选内容按照预设的缩进规则进行缩进。Rewrap Paragraph:重新换行段落。将一段文字根据指定宽度重新排版。Visualize Whitespace:可视化空白字符。显示通常不可见的空格、制表符等空白…

element ui 精确控制日期控件 date-picker

https://github.com/element-plus/element-plus/discussions/17378 -- 某组件 xxx.vue ... <el-date-pickerv-model"timeRange"type"daterange"range-separator"-"start-placeholder"开始日期"end-placeholder"结束日期"…

QTday1代码的形式实现登录框

代码注释 main.cpp #include "widget.h"#include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);//调用应用程序类的有参构造的实例化对象Widget w;//调用自定义的有参构造实例化的对象w.show();//调用该类的父类里的成员函数…

spring6启用Log4j2日志

pom文件 <!--log4j2的依赖--> <dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.23.1</version> </dependency> <dependency><groupId>org.apache…

C++入门编程题(力扣):字符串中最多数目的子序列

1.题目描述&#xff1a; 给你一个下标从0开始的字符串 text 和另一个下标从0开始且长度为 2 的字符串 pattern两者都只包含小写英文字母。 你可以在 text 中任意位置插入 一个 字符&#xff0c;这个插入的字符必须是 pattern[0]或者 pattern[1]。 注意&#xff0c;这个字符可以…

Spring Boot 基础入门指南

1. 什么是 Spring Boot&#xff1f; Spring Boot 是一个用于简化 Spring 应用程序开发的框架&#xff0c;旨在让开发者快速构建独立的、生产级的 Spring 应用。它提供了自动配置、嵌入式服务器和一系列开箱即用的功能&#xff0c;降低了应用程序的开发和部署难度。 2. Spring…

青动CRM V3.2.1

全面解决企业销售团队的全流程客户服务难题旨在助力企业销售全流程精细化、数字化管理&#xff0c;全面解决企业销售团队的全流程客户服务难题&#xff0c;帮助企业有效盘活客户资源、量化销售行为&#xff0c;合理配置资源、建立科学销售体系&#xff0c;提升销售业绩。标准授…