This commit is contained in:
1AoB 2024-04-22 15:32:54 +08:00
parent 1f66652fd4
commit b384243156

View File

@ -20,12 +20,13 @@ This article offers a sample of basic Markdown.
## 1.简要的描述一下你的项目? ## 1.简要的描述一下你的项目?
智能音箱主要是模仿小米的小爱音箱做的。项目采用 C/S 架构,分成了三个 智能音箱主要是模仿小米的小爱音箱做的。项目采用 C/S 架构,分成了三个
部分,音箱部分、后台阿里云服务器以及 APP 部分,arm音箱部分、后台c++服务器以及qt客户端
音箱部分基于 mini2440 开发板,移植了 Linux 操作系统,包括 u-boot、内 音箱部分基于 mini2440 开发板,移植了 Linux 操作系统,包括 u-boot、操作系统
根文件系统。应用层使用开源库 madplay 作为音频的编解码工具,采用父、 以及根文件系统。应用层使用开源库 madplay 作为音频的编解码工具,采用父、
子、孙三个进程来控制音乐的播放。通过按键实现切歌、调节音量、暂停等功能。 子、孙三个进程来控制音乐的播放。通过按键实现切歌、调节音量、暂停等功能。
后台阿里云服务器是一个公网服务器用的C++语言,可以实现 APP 数据的 后台阿里云服务器是一个公网服务器使用C++语言,可以实现 APP 数据的转发,充当一个中转站的角色。
转发。因为服务器选择使用开源高并发框架libevent 来实现。服务器还加入了链表的功能,记录 APP 和音箱的绑定关系。
服务器选择使用开源高并发框架libevent 来实现。服务器还加入了链表的功能,记录 APP 和音箱的绑定关系。
APP客户端 用 Qt 实现,主要负责往服务器发送控制指令,包括切歌、调节音量、 APP客户端 用 Qt 实现,主要负责往服务器发送控制指令,包括切歌、调节音量、
播放模式、语音控制等等,然后服务器再转发给音箱 播放模式、语音控制等等,然后服务器再转发给音箱
@ -39,163 +40,250 @@ APP客户端 用 Qt 实现,主要负责往服务器发送控制指令,包括
解决。所以用 C++开发效率更高、运行也会更加稳定。而且C++因为有继承和多 解决。所以用 C++开发效率更高、运行也会更加稳定。而且C++因为有继承和多
态的存在,代码的重用性更好,一份代码可以用在不同的项目中,后期维 护更 态的存在,代码的重用性更好,一份代码可以用在不同的项目中,后期维 护更
低。 低。
## 4、mini2440 是一块什么样的开发板,用的是什么芯片? ## 4、mini2440 是一块什么样的开发板,用的是什么芯片?
mini2440 还是一块比较老的开发板,用的三星的 S3C 2440 单核处理器ARM9 mini2440 还是一块比较老的开发板,用的三星的 S3C 2440 单核处理器ARM9
内核64M SDRAM 和 256M NandFlash性能不算强大比较适合用于学习。 内核64M SDRAM 和 256M NandFlash性能不算强大比较适合用于学习。
## 5、u-boot 源码看过吗?他的启动流程是什么样的?(完成了哪些功
能)
u-boot 我自己动手编译过,直接用的 mini2440 开发板定制的配置文件。启
动流程了解一些,分为两个阶段,第一个阶段设置 CPU 工作模式为 SVC关闭中断、 - 补充请简要介绍一下Linux开发板中的Bootloader是什么以及它的作用和优势。
看门狗、MMU、cache、初始化内存、串口、设置栈为运行 C 语言做准备, 然后
跳到 C 语言开始执行。第二个阶段主要是初始化外设、进入循环处理用户的指令。 在Linux开发板中Bootloader是一个特别设计的小型程序它存储在开发板的非易失性存储器中是系统上电或重启后首先被执行的代码。Bootloader的核心作用是为系统的启动准备环境将操作系统内核加载到内存中并执行。
## 5、u-boot 源码看过吗?他的启动流程是什么样的?(完成了哪些功能)
u-boot源码没有看过 , 但是我自己动手编译过,直接用的 mini2440 开发板定制的配置文件。启
动流程了解一些,分为两个阶段:
- 第一个阶段设置 CPU 工作模式为 SVC关闭中断、
看门狗、MMU、cache(高速缓冲存储器)、初始化内存、串口、设置栈,为运行 C 语言做准备, 然后
跳到 C 语言开始执行。
- 第二个阶段主要是初始化外设、进入循环处理用户的指令。
## 6、移植内核的时候你做了哪些事情 ## 6、移植内核的时候你做了哪些事情
移植内核的时候用了 mini2440 开发板定制的配置文件,所以配置内核没有花 移植内核的时候用了 mini2440 开发板定制的配置文件,所以配置内核没有花什么时间,就是添加了对 cram 文件系统格式的支持。然后开始arm-linux-32交叉编译最后烧写到开发板的 NandFlash 中。(最好了解下 NorFlash 和 NandFlash 的区别)
什么时间,就是添加了对 cram 文件系统格式的支持。然后开始交叉编译,最后烧
写到开发板的 NandFlash 中。(最好了解下 NorFlash 和 NandFlash 的区别) 开发板上有一个上下推拉按钮,一开始烧录uboot.bin文件时,先推到上面的norflash,等烧录完成后,我再关闭开发板的电源,将按钮推到nandflah,再开启电源,使用xshell通过串口进行连接就可以了,连接的端口不固定,有时是com5,有时是com6,连接之前最好在电脑上的设备管理器中段端口进行查看一下啊,连接成功后,就可以在xshell中操作开发板的Linux系统了.因为开发板的内存有限,所以我并没有选择在开发版的操作系统中进行Linux编程,我是先在vm上安装一个红帽系统,在上面进行编程,然后把交叉编译后的二进制文件通过tftp工具传输到开发板上.
## 7、项目中使用了哪些开源库 ## 7、项目中使用了哪些开源库
用于音频解码的 madplay网络数据传输使用的 json 格式,音箱上面移植 用于音频解码的 madplay网络数据传输使用的 json 格式,音箱上面移植了 json-c服务器用的 jsoncpp 和 libeventQt上用了 QJson,以及网络和数据库等模块。
了 json-c服务器用的 jsoncpp 和 libeventQt上用了 QJson。
## 8、工程文件的编译方式你知道哪些 ## 8、工程文件的编译方式你知道哪些
编译 json 的时候遇到过两种方式,一个是用 configure一个是用 cmake 编译 json 的时候遇到过两种方式,一个是用 configure一个是用 cmake
两种都是为了产生 Makefile 文件来完成工程的编译。configure 是一个脚本,
属于 autotools 工具集autotools 有很多工具autoscan、autoconf、 两种都是为了产生 Makefile 文件来完成工程的编译。configure 是一个sh脚本
autoheadler通过这些工具可以自动生成 Makefile 文件。configure 文件就是
这些工具的一个中间产物,运行 configure 脚本,可以自动检查和配置编译环境, 属于 autotools 工具集autotools 有很多工具autoscan、autoconf、autoheadler通过这些工具可以自动生成 Makefile 文件。configure 文件就是这些工具的一个中间产物,运行 configure 脚本,可以自动检查和配置编译环境,生成 Makefile 文件。
生成 Makefile 文件。
但是 autotools 工具步骤太多,所以现在就有了 CMake通过CMakeList.txt 但是 autotools 工具步骤太多,所以现在就有了 CMake通过CMakeList.txt来指定编译规则运行 cmake 命令也可以产生 Makefile。
来指定编译规则,运行 cmake 命令也可以产生 Makefile。 项目中因为使用了交叉编译,配置交叉编译用 configure 更方便,所以我选择了通过 configure 来产生 Makefile 文件。
项目中因为使用了交叉编译,配置交叉编译用 configure 更方便,所以我选
择了通过 configure 来产生 Makefile 文件。
## 9、移植开源库是什么样的步骤 ## 9、移植开源库是什么样的步骤
先是通过 configure 脚本配置编译环境,设置目标架构、交叉编译工具以及安 1.先是通过 configure 脚本配置编译环境,设置目标架构、交叉编译工具以及安装目录,这一步同时会<font color=red>生成 makefile 文件</font>
装目录,这一步同时会生成 makefile 文件,然后通过 make 命令执行 makefile
开始编译,编译完成后执行 make install 把目标文件安装到指定的目录,我就 2.然后通过 make 命令对 makefile进行编译
是把目标文件安装到交叉工具链的目录里面。
3.编译完成后执行 make install 把目标文件安装到指定的目录,我就是把目标文件安装到交叉工具链的目录里面。
## 10、播放音乐为什么选择多进程使用多线程能完成吗 ## 10、播放音乐为什么选择多进程使用多线程能完成吗
播放音乐使用了三个进程,父进程负责监听服务器和按键信息,收到开始播 播放音乐使用了三个进程,
放消息的时候创建子进程,子进程创建孙进程,孙进程负责音乐的播放,子进程
通过 wait 函数阻塞,等待孙进程播放结束回收孙进程的资源。多线程也可以完 1.父进程负责 <font color=red>监听服务器和按键信息</font> ,收到开始播放消息的时候创建子进程,
成,主要是考虑到进程比较健壮,如果主进程死了不会影响播放音乐的进程,这样
用户体验会更好一些。 2.子进程创建孙进程,孙进程负责音乐的播放,子进程通过 wait 函数阻塞,等待孙进程播放结束来回收孙进程的资源。
> (如果只创建两个进程,那就没有经常可以回收播放音乐的进程,父进程忙着监听服务器和按键事件,肯定不能用wait阻塞)
>
> {如果非要使用两个进程,可以让音乐进程结束时,让音乐进程向父进程发送一个信号,父进程可以再处理函数中执行资源回收的工作.}
多线程也可以完成,主要是考虑到进程比较健壮,如果主进程死了不会影响播放音乐的进程,这样用户体验会更好一些。
在多线程应用中,所有线程共享一个进程的资源和地址空间,如果主线程发送了崩溃或非正常终止,整个进程以及器内部的所有线程通常都会受到影响,从而导致整个应用程序终止.
## 11、父子孙三个进程需要通信吗使用的是哪种通信方式 ## 11、父子孙三个进程需要通信吗使用的是哪种通信方式
需要通信,用了共享内存和信号。父进程需要把播放模式传递给孙进程,子进 需要通信用了shm共享内存和信号。
程和孙进需要把当前正在播放的音乐以及进程号传递给父进程。数据的传递使用
的是共享内存。父进程控制子进程和孙进程的暂停继续使用的是信号。 父进程需要把播放模式传递给孙进程,
子进程和孙进需要把当前正在播放的音乐以及进程号传递给父进程。
数据的传递 使用的是 shm共享内存。父进程控制子进程和孙进程的暂停继续 , 使用的是信号。
## 12、Linux 有哪些 IPC 方式?各自的优缺点是什么? ## 12、Linux 有哪些 IPC 方式?各自的优缺点是什么?
无名管道、有名管道、信号、消息队列、共享内存、信号量以及套接字。无名管道 无名管道、有名管道、信号、消息队列、共享内存、信号量以及套接字。
只能用于父子进程,有名管道可以用于任意两个进程,管道比较简单,但是只能
传输没有格式的字节流。信号传递的数据量有限,一般只是用于进程的控制。消 无名管道只能用于父子进程,
息队列可以传输有格式的数据。共享内存传输效率最高,因为可以直接读写内存。
信号量主要用于进程的同步。套接字属于网络传输,也算是一种进程间通信。 有名管道可以用于任意两个进程,管道比较简单,但是只能传输没有格式的字节流。信号传递的数据量有限,一般只是用于进程的控制。
消息队列可以传输有格式的数据。
共享内存传输效率最高,因为可以直接读写内存。信号量主要用于进程的同步。
套接字属于网络传输,也算是一种进程间通信。
## 13、进程和线程的区别有哪些各有什么优势 ## 13、进程和线程的区别有哪些各有什么优势
进程和线程的根本区别是进程是操作系统资源分配的基本单位,而线程是处 进程和线程的根本区别是:
理器任务调度和执行的基本单位。
进程是操作系统<font color =red>资源分配</font>的基本单位,
而线程是处理器<font color =red>任务调度和执行</font>的基本单位。
资源开销:每个进程都有独立的代码和数据空间(程序上下文),程序之间 资源开销:每个进程都有独立的代码和数据空间(程序上下文),程序之间
的切换会有较大的开销;线程共享代码和数据空间,线程之间切换的开销小。 的切换会有较大的开销;线程共享代码和数据空间,线程之间切换的开销小。
包含关系:一个进程可以包含多个线程。 包含关系:一个进程可以包含多个线程。
内存分配:同一进程内的线程共享本进程的地址空间和资源,而进程之间的地 内存分配:同一进程内的线程,共享本进程的地址空间和资源,而进程之间的地
址空间和资源是相互独立的。 址空间和资源,是相互独立的。
影响关系:一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一 影响关系:一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一
个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。 个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。
执行过程:进程有独立的入口,就是 main 函数,线程不能单独运行,只能 执行过程:进程有独立的入口,就是 main 函数,线程不能单独运行,只能
由进程创建然后开始运行。 由进程创建然后开始运行。
进程的优点就是健壮,不容易死掉;线程开销小、切换快,而且没有复杂的 进程的优点就是健壮,不容易死掉;线程开销小、切换快,而且没有复杂的
通信机制,定义一个全局变量就都可以访问。 通信机制,定义一个全局变量就都可以访问。
## 14、音箱是如何实现同时接收阿里云服务器的消息和按键消息的 ## 14、音箱是如何实现同时接收阿里云服务器的消息和按键消息的
用了 select 机制,把按键的设备文件对应的文件描述符和 socket 对应的文 用了 select 机制,把按键的设备文件对应的文件描述符和 socket 对应的文
件描述符放在一个集合里面同时监听,监听到数据后再去判断到底是网络消息还 件描述符放在一个集合里面同时监听,监听到数据后再去判断到底是网络消息还
是按键消息,然后再去调用不同的处理函数。 是按键消息,然后再去调用不同的处理函数。
## 15、后台服务器为什么选择阿里云服务器 ## 15、后台服务器为什么选择阿里云服务器
服务器只要是公网服务器都行,阿里云、华为云、腾讯云都可以,当时看阿 服务器只要是公网服务器都行,阿里云、华为云、腾讯云都可以,当时看阿里云便宜就选择了阿里云。
里云便宜就选择了阿里云。
## 16、服务器是怎么解决高并发问题的能同时处理多少个音箱 ## 16、服务器是怎么解决高并发问题的能同时处理多少个音箱
服务器用的一个高并发网络框架libeventlibevent在Linux上是通过epoll来 服务器用的一个高并发网络框架libeventlibevent在Linux上是通过epoll来
实现的,是一种效率比较高的多路复用技术,一个集合,里面有很多事件,一个 实现的,(epoll)是一种效率比较高的多路复用技术,一个集合,里面有很多事件,一个
事件对应一个客户端,不断的循环遍历集合,判断有没有客户端发送数据过来。 事件对应一个客户端,不断的循环遍历集合,判断有没有客户端发送数据过来。
它不会像多线程一样消耗过多的硬件资源。 它不会像多线程一样消耗过多的硬件资源。
我写了一个脚本,用虚拟机模拟启动了 100 个音箱和 100 个客户端,运行比 我写了一个sh脚本,用虚拟机模拟启动了 100 个音箱和 100 个客户端,运行比
较慢,但是收发消息都正常。最多能处理多少个没试过,这个得取决于服务器软硬 较慢,但是收发消息都正常。最多能处理多少个没试过,这个得取决于服务器软硬
件性能吧。 件性能吧。
## 17、你知道哪些并发服务器模型有什么优缺点吗 ## 17、你知道哪些并发服务器模型有什么优缺点吗
我知道有多进程、多线程、UDP、select、epoll。多进程的并发服务器开销比 我知道有多进程、多线程、UDP、select、epoll。多进程的并发服务器开销比
较大,因为每个进程都要独立的地址空间,所以效率并不高。多线程服务器资源开 较大,因为每个进程都要独立的地址空间,所以效率并不高。多线程服务器资源开
销确实比较小但是线程同步又会比较麻烦要加上一些同步机制。UDP 其实算是 销确实比较小,但是线程同步又会比较麻烦,要加上一些同步机制。
循环服务器谈不上并发。Select 能监听的文件描述符个数有上限,而且每次都得
UDP 其实算是循环服务器谈不上并发。Select 能监听的文件描述符个数有上限,而且每次都得
遍历集合找到活跃的文件描述符这个影响效率。Epoll 比 select 效率高,他 遍历集合找到活跃的文件描述符这个影响效率。Epoll 比 select 效率高,他
是通过事件的方式通知应用层,省去了遍历集合这个环节。 是通过事件的方式通知应用层,省去了遍历集合这个环节。
- 补充UDP 其实算是循环服务器,谈不上并发。
为什么这么说?
UDPUser Datagram Protocol用户数据报协议通常被描述为一种无连接的、不可靠的协议。与TCPTransmission Control Protocol传输控制协议不同UDP不建立连接不保证数据包的顺序、可靠传输或数据完整性。
在UDP服务器中通常只有一个主循环这个循环监听从客户端到来的数据报文datagrams。当数据报文到达时服务器处理这个数据报文然后继续等待下一个数据报文的到来。这个处理过程是顺序的每次只处理一个数据报文因此在基本的UDP服务器设计中并没有并发处理数据报文的机制。
## 18、你刚才提到了线程同步线程同步你用过哪些方法 ## 18、你刚才提到了线程同步线程同步你用过哪些方法
线程同步用过互斥锁、信号量和条件变量。 线程同步用过互斥锁、信号量和条件变量。
## 19、互斥锁和信号量有什么区别 ## 19、互斥锁和信号量有什么区别
互斥锁只有两种状态,要么上锁,要么没上锁,同一时刻只允许一个线程访 互斥锁只有两种状态,要么上锁,要么没上锁,同一时刻只允许一个线程访
问共享资源。信号量分为二值信号量和计数信号量,如果是二值信号量也只有两种 问共享资源。
信号量分为二值信号量和计数信号量,如果是二值信号量也只有两种
状态,如果是计数信号量可以有多种状态,同一时刻可以允许多个进程访问共享资 状态,如果是计数信号量可以有多种状态,同一时刻可以允许多个进程访问共享资
源。 源。
## 20、如果有多个APP 和多个音箱,你这服务器能处理吗? ## 20、如果有多个APP 和多个音箱,你这服务器能处理吗?
可以处理的,我在服务器端创建了一个链表,保存了 APP 和音箱的绑定的关 可以处理的,我在服务器端创建了一个链表,保存了 APP 和音箱的绑定的关
系。第一次使用 APP 的时候,必须要输入手机号和音箱的产品 ID 号,在服务器 系。第一次使用 APP 的时候必须要输入app id号和音箱的设备ID 号,在服务器
端记录两者的绑定关系,所以一个 APP 最终只能控制一个音箱。 端记录两者的绑定关系,所以**一个 APP 最终只能控制一个音箱**。
## 21、服务器端是如何保存APP 和音箱数据的? ## 21、服务器端是如何保存APP 和音箱数据的?
服务器端用了 MySQL 数据库,保存了音箱和 APP 的绑定关系,可以防止服务 服务器端有一个链表,链表里面除了加入了 APP 和音
器程序结束后这种绑定关系丢失。还有一个链表,链表里面除了加入了 APP 和音
箱的绑定关系,还记录了他们的在线状态,这样 APP 发送指令的时候,服务器 箱的绑定关系,还记录了他们的在线状态,这样 APP 发送指令的时候,服务器
就可以先判断对方是否在线,再选择发送。 就可以先判断对方是否在线,再选择发送。
## 22、服务器除了选择libevent实现还有其他方式吗 ## 22、服务器除了选择libevent实现还有其他方式吗
TCP+多线程、UDP、select或者直接使用libevent的底层实现 epoll 都可 TCP+多线程、UDP、select或者直接使用libevent的底层实现 epoll 都可
以实现。协议的话 TCP 比较合适,因为 TCP 安全可靠,而且我发送的指令数据 以实现。协议的话 TCP 比较合适,因为 TCP 安全可靠,而且我发送的指令数据
量并不大。select 的话能处理的文件描述符数量有限,所以用作高并发不太合适, 量并不大。select 的话能处理的文件描述符数量有限,所以用作高并发不太合适,
多线程太占用系统资源epoll 效果应该是最好的。 多线程太占用系统资源epoll 效果应该是最好的。
## 23、你对多路IO 复用技术了解多少? ## 23、你对多路IO 复用技术了解多少?
Linux 里面主要有 select、poll 和 epoll 三个select 效率比较低,因为 Linux 里面主要有 select、poll 和 epoll 三个select 效率比较低,因为
它只是知道了有 IO 事件发生,至于是哪个,还要循环查找所有的文件描述符, 它只是知道了有 IO 事件发生,至于是哪个,还要循环查找所有的文件描述符,
然后进行读写操作。而且 select 能监听的文件描述符个数有数量限制。 然后进行读写操作。而且 select 能监听的文件描述符个数有数量限制。
poll 和 select 本质没有区别,效率也不高。但是它没有文件描述符个数的 poll 和 select 本质没有区别,效率也不高。但是它没有文件描述符个数的
限制,因为它是基于链表实现的。 限制,因为它是基于链表实现的。
epoll 不同于 select 和 poll它是通过事件完成的一旦有 IO 事件发生,会自动通知应用层,省去了循环遍历的麻烦。所以 epoll 的效率不会随着文件描 epoll 不同于 select 和 poll它是通过事件完成的一旦有 IO 事件发生,会自动通知应用层,省去了循环遍历的麻烦。所以 epoll 的效率不会随着文件描述符数量的增加而降低。
述符数量的增加而降低。
(他们的缺点是什么?都是同步 IO。什么是同步 IO异步 IO ## (他们的缺点是什么?都是同步 IO。什么是同步 IO异步 IO
## 24、客户端和服务器的通信选择了哪种协议为什么选择了这种协 ## 24、客户端和服务器的通信选择了哪种协议为什么选择了这种协
议? 协议选择了 TCP 协议TCP 安全、可靠、基于流tcp是流式传输协议udp是报式传输协议
选择了 TCP 协议TCP 安全、可靠、基于流,项目中客户端和服务器主要是
传输一些指令,数据量不大,但是对安全性要求比较高,所以就选择了 TCP。我 项目中客户端和服务器主要是传输一些指令,数据量不大,但是对安全性以及完整性要求比较高,所以就选择了 TCP。
也比较过 TCP 和 UDPUDP 简单但是不安全,比较适合传输大量的数据,比如图
我也比较过 TCP 和 UDPUDP 简单但是不安全,不可靠,容易丢包,比较适合传输大量的数据,比如图
片数据、音视频数据。 片数据、音视频数据。
## 25、描述一下TCP 的三次握手和四次挥手。 ## 25、描述一下TCP 的三次握手和四次挥手。
三次握手是指客户端和服务器建立连接的过程。第一次握手Client 将标志 三次握手是指客户端和服务器建立连接的过程。
位 SYN 置为 1随机产生一个值 seq=J并将该数据包发送给 ServerClient 进
入 SYN_SENT 状态,等待 Server 确认。第二次握手Server 收到数据包后由标志 1第一次握手Client 将标志位 SYN 置为 1随机产生一个值 seq=J并将该数据包发送给 Server
位 SYN=1 知道 Client 请求建立连接Server 将标志位 SYN 和 ACK 都置为 1
ack=J+1随机产生一个值 seq=K并将该数据包发送给 Client 以确认连接请求, Client 进入 SYN_SENT 状态,等待 Server 确认。
Server 进入 SYN_RCVD 状态。第三次握手Client 收到确认后,检查 ack 是否为
2第二次握手Server 收到数据包后由标志
位 SYN=1 知道 Client 请求建立连接,
Server 将标志位 SYN 和 ACK 都置为 1
ack=J+1随机产生一个值 seq=K
并将该数据包发送给 Client 以确认连接请求,
Server 进入 SYN_RCVD 状态。
3第三次握手Client 收到确认后,检查 ack 是否为
J+1ACK 是否为 1如果正确则将标志位 ACK 置为 1ack=K+1并将该数据包发 J+1ACK 是否为 1如果正确则将标志位 ACK 置为 1ack=K+1并将该数据包发
送给 ServerServer 检查 ack 是否为 K+1ACK 是否为 1如果正确则连接建立 送给 ServerServer 检查 ack 是否为 K+1ACK 是否为 1
成功Client 和 Server 进入 ESTABLISHED 状态,完成三次握手,随后 Client 与
如果正确则连接建立
成功Client 和 Server 进入 ESTABLISHED一丝淡薄里斯确定的 状态,完成三次握手,随后 Client 与
Server 之间可以开始传输数据了。 Server 之间可以开始传输数据了。
----
四次挥手是指服务器和客户端断开连接的过程,既可以是服务器发起,也可 四次挥手是指服务器和客户端断开连接的过程,既可以是服务器发起,也可
以是客户端发起。第一次挥手Client 发送一个 FIN用来关闭 Client 到Server 以是客户端发起。
的数据传送Client 进入 FIN_WAIT_1 状态。第二次挥手Server 收到 FIN 后,
第一次挥手Client 发送一个 FIN用来关闭 Client 到Server
的数据传送Client 进入 FIN_WAIT_1 状态。
第二次挥手Server 收到 FIN 后,
发送一个 ACK 给 Client确认序号为收到序号+1与 SYN 相同,一个 FIN 占用一 发送一个 ACK 给 Client确认序号为收到序号+1与 SYN 相同,一个 FIN 占用一
个序号Server 进入 CLOSE_WAIT 状态。第三次挥手Server 发送一个 FIN 个序号Server 进入 CLOSE_WAIT 状态。
来关闭 Server 到 Client 的数据传送Server 进入 LAST_ACK 状态。第四次挥手,
第三次挥手Server 发送一个 FIN
来关闭 Server 到 Client 的数据传送Server 进入 LAST_ACK 状态。
第四次挥手,
Client 收到 FIN 后Client 进入 TIME_WAIT 状态,接着发送一个 ACK 给Server Client 收到 FIN 后Client 进入 TIME_WAIT 状态,接着发送一个 ACK 给Server
认序号为收到序号+1Server 进入 CLOSED 状态,完成四次挥手。 认序号为收到序号+1Server 进入 CLOSED 状态,完成四次挥手。
## 26、如何保证APP 端的数据一定能被音箱收到?
## 26、如何保证qtAPP 端的数据一定能被音箱收到?
我模拟了 TCP 协议的超时重传机制APP 发送指令给服务器,服务器转发给 我模拟了 TCP 协议的超时重传机制APP 发送指令给服务器,服务器转发给
音箱,音箱收到数据后还要回复服务器,服务器再回复 APP所以 APP 只有收到 音箱,音箱收到数据后还要回复服务器,服务器再回复 APP所以 APP 只有收到
了服务器的回复才认为消息发送成功,如果超过规定的时间还没有收到,会再次 了服务器的回复才认为消息发送成功,如果超过规定的时间还没有收到,会再次
发送数据。超时时间是通过 setsockopt 函数来设置的。 发送数据。超时时间是通过 setsockopt 函数来设置的。
## 27、如果在使用的过程中由于网络问题音箱掉线了怎么处理的 ## 27、如果在使用的过程中由于网络问题音箱掉线了怎么处理的
为了保证音箱时刻在线,我在项目中添加了一种保活机制,就是音箱每隔 5 为了保证音箱时刻在线,我在项目中添加了一种保活机制,就是音箱每隔 1
秒钟向服务器发送一帧数据,表示音箱还在线。所以如果超过 10S 服务器没有收 秒钟向服务器发送一帧数据,表示音箱还在线。所以如果当前的时间节点-上一次保活的时间节点,超过 1S 服务器都没有收到数据,就可以判定音箱掉线了,这个时候服务器会通知 APP。
到数据,就可以判定音箱掉线了,这个时候服务器会通知 APP。28、网络传输数据为什么选择了 json 传输?尝试过其他格式吗?
## 28、网络传输数据为什么选择了 json 传输?尝试过其他格式吗?
json 用起来更加灵活,不像结构体那样庞大,需要发送什么就添加什么键 json 用起来更加灵活,不像结构体那样庞大,需要发送什么就添加什么键
值对。其他格式听说过 XML 和 YAML但是没有使用过。 值对。其他格式听说过 XML 和 YAML但是没有使用过。
## 29、Qt 端的语音识别是怎么实现的? ## 29、Qt 端的语音识别是怎么实现的?
语音识别用的是百度 AI 平台提供的接口,先把语音录制成音频文件,然后 语音识别用的是百度 AI 平台提供的接口,先把语音录制成音频文件,然后
通过 HTTP 方式向百度服务器发起请求,最终返回识别的结果。 通过 HTTP 方式向百度服务器发起请求,最终返回识别的结果。
## 30、APP 为什么选择 Qt没有做 Android 或者 IOS 吗? ## 30、APP 为什么选择 Qt没有做 Android 或者 IOS 吗?
我在学校的时候学过 C++Qt 是 C++的一个应用,用的就是 C++语言,而且 Qt 是 C++的一个应用,用的就是 C++语言,而且
他的跨平台性比较好Linux 和 Windows 都可以使用。Android 和 IOS 没有研究 他的跨平台性比较好Linux 和 Windows 都可以使用。Android 和 IOS 没有研究
过。 过。
## 31、说一说 Qt 的信号与槽机制。 ## 31、说一说 Qt 的信号与槽机制。
信号与槽是 Qt 里面的一个重要机制,主要是方便各个组件之间的交互。信 信号与槽是 Qt 里面的一个重要机制,主要是方便各个组件之间的交互。信
号就是在特定情况下发生的事件,比如 button 被点击是一个事件、输入框按下 号就是在特定情况下发生的事件,比如 button 被点击是一个事件、输入框按下
@ -206,10 +294,10 @@ json 用起来更加灵活,不像结构体那样庞大,需要发送什么就
中连接槽函数。信号可以有参数,但是不能有返回值。 中连接槽函数。信号可以有参数,但是不能有返回值。
## 33、做项目的过程中你遇到了哪些问题是怎么解决的 ## 33、做项目的过程中你遇到了哪些问题是怎么解决的
印象比较深的是音箱连不上服务器,后来我自己在本地写了一个服务器程 印象比较深的是音箱连不上服务器,后来我自己在本地写了一个服务器程
序,可以连上,大概确认了音箱程序没有问题。然后百度了一下连不上的原因, 序,可以连上,大概确认了音箱程序没有问题。
发现是阿里云没有添加对应的协议和端口号... (这个问题出现的概率比较高,自己可以准备两个答案,一定要体现出解决
问题的过程解决方法可以是百度、Google 或者是 Stack Overflow后两个网 然后在Google 或者是 Stack Overflow上查了一下连不上的原因
站是程序员解决问题的首选网站,可以尝试使用使用) 发现是阿里云你需要自己在安全组 添加对应的协议和端口号...
## 34、你觉得这个项目还有哪些地方需要改进 ## 34、你觉得这个项目还有哪些地方需要改进