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()
传输的数据距离开,而后在接收端基于这些距离数据的标识将数据拆分或合并。