本文列举了一些常用的 shell 指令。
本文列举了一些常用的 shell 指令。
多路复用 IO 模型中的函数介绍。
为了解决网络 IO 中的问题,学者们提出了 4 种网络 IO 模型: 阻塞 IO 模型、非阻塞 IO 模型、多路 IO 复用模型和异步 IO 模型。
HTTPS 简介。
本文介绍了“粘包”问题的概念、原因以及解决方法。
由于 TCP “流”的特性以及网络状况,在进行数据传输时假设我们连续调用两次 send 分别发送两段数据 data1 和 data2,在接收端有以下几种接收情况(当然不止这几种情况,这里只列出了有代表性的情况):
对于第一种情况正是我们需要的,不再做讨论。对于后三种情况就是常说的“粘包”,就需要把接收到的数据进行拆包,拆成一个个独立的数据包。而为了拆包就必须在发送端进行封包。
对于 UDP 来说就不存在拆包的问题,因为 UDP 是个”数据包”协议,也就是两段数据间是有界限的,在接收端要么接收不到数据要么就是接收一段完整的数据,不会少接收也不会多接收。
TCP 协议是基于字节流的传输层协议,其中不存在消息和数据包的概念。应用层协议没有使用基于长度或者基于终结符的消息边界,导致多个消息的粘连。
粘包可发生在发送端也可发生在接收端。原因如下:
最初遇到粘包的问题时,大家可能觉得可以在两次 send 之间调用 sleep 来休眠一小段时间,以此来解决。这个解决方法的缺点是显而易见的:使传输效率大大降低,而且也并不可靠。
对于发送方造成的粘包现象,可以通过关闭 Nagle 算法来解决,使用 TCP_NODELAY 选项来关闭 Nagle 算法。但是无法解决接收方粘包的问题。在应用层对数据包进行封包和拆包,就能解决这个问题。
封包就是给一段数据加上包头,这样一来数据包就分为包头和包体两部分内容了(过滤非法包时会加上“包尾”内容)。包头其实上是个大小固定的结构体,其中有个结构体成员变量表示包体的长度,这是个很重要的变量,其他的结构体成员可根据需要自己定义。根据固定的包头长度以及包头中含有的包体长度的变量值就能正确的拆分出一个完整的数据包。
利用底层的缓冲区来进行拆包时,由于 TCP 也维护了一个缓冲区,所以可以利用 TCP 的缓冲区来缓存发送的数据,这样一来就不需要为每一个连接分配一个缓冲区了,对于利用缓冲区来拆包,也就是循环不停地接收包头给出的数据,直到收够为止,这就是一个完整的 TCP 包。
为了解决粘包的问题,大家通常会在所发送的内容前加上发送内容的长度,所以对方就会先收 4 Byte,解析获得接下来需要接收的长度,再进行收包。
《后台开发:核心技术与应用实践》
为什么 TCP 协议有粘包问题
TCP 的拥塞控制由 4 个核心算法组成:慢开始、 拥塞避免、快速重传和快速恢复。
TCP 流量控制图解,来自《图解 TCP/IP》。
TCP 滑动窗口图解,来自《图解 TCP/IP》。
TCP 是一种面向连接的单播协议,在发送数据前,通信双方必须在彼此间建立一条连接。所谓的“连接”,其实是客户端和服务器的内存里保存的一份关于对方的信息,如 IP 地址、端口号等。TCP 可以看成是一种字节流,它会处理 IP 层或以下的层的丢包、重复以及错误问题。在连接的建立过程中,双方需要交换一些连接的参数。这些参数可以放在 TCP 头部。TCP 提供了一种可靠、面向连接、字节流、传输层的服务,采用三次握手建立一个连接,采用四次挥手来关闭一个连接。
以文本形式打开 svg 文件,修改 height 和 width 项,将其改成想要的分辨率,然后使用 AI 等矢量图编辑软件导出到 pdf 即可。