共计 934 个字符,预计需要花费 3 分钟才能阅读完成。
TCP
Nagle 算法
如果每次发送一个很小的数据包,比方一个字节内容的数据包而不优化,就会导致网络中只有极少数无效数据的数据包,这会导致节约大量的网络资源。Nagle 算法针对这种状况,要求缓存区的数据达到肯定数据量或者肯定工夫后才将其收回,所以数据包将会被 Nagle 算法合并,以此来优化网络。这种优化尽管进步了网络带宽的效率,但有的数据可能会被提早发送。
在 Nodejs 中,因为 TCP 默认启动 Nagle 算法,能够调用 socket.setNoDelay(ture)
去掉 Nagle 算法,使得 write()
能够立刻发送数据到网络中。但须要留神的是,只管在网络的一端调用 write()
会触发另一端的 data 事件,然而并不是每次 write()
都会触发另一端的 data 事件,在敞开 Nagle 算法后,接收端可能会将接管到的多个小数据包合并,而后只触发一次 data 事件。也就是说 socket.setNoDelay(ture)
只能解决一端的 数据粘包 问题。
什么是粘包?
在组包过程中,把上一个包的内容与下一个包里的粘在了一起被谬误地当成了一个数据包解析了进去。这就是所谓的粘包。
粘包呈现的根本原因是不确定音讯的边界。接收端在面对 ” 无边无际 ” 的二进制流的时候,基本不晓得收了多少 01 才算一个音讯。一不小心拿多了就说是粘包。其实粘包基本不是 TCP 的问题,是使用者对于 TCP 的了解有误导致的一个问题。
只有在发送端每次发送音讯的时候给音讯带上辨认音讯边界的信息,接收端就能够依据这些信息辨认出音讯的边界,从而辨别出每个音讯。
通过拆包封包的形式解决粘包计划
node.js 中,不会依照发送端的 write
写入对应触发接收端的 data 事件,它会有以下 3 种状况:
- 发送端屡次
write()
的数据可能被打包成一个数据包发送到接收端。 - 发送端通过
write()
一次写入的数据可能因为体积过大被截断到多个数据包中 - 发送端通过
write()
一次写入打包成一个数据报发送到接收端
咱们要解决就是前 2 中状况。TCP 是基于流的传输机制,那么它的数据程序在传输过程中是确定的先进先出准则。所以,能够通过在每次 write()
在数据头部增加一些标识,将每次 write()
传输的数据距离开,而后在接收端基于这些距离数据的标识将数据拆分或合并。