【发布时间】:2020-03-13 07:06:12
【问题描述】:
我正在做一个学校项目来实现一些算法,我可以通过根据数据包丢失增加或减少来动态改变从客户端发送到服务器的数据包速率。
问题是它只能在每次发送 4 个数据包之前工作,然后,它开始合并数据包并将它们一起发送,所以我无法确定是否有数据包丢失。
无论如何我可以阻止 TCP 执行该行为吗?
客户端代码:
const net = require('net')
const PORT = 8550
const HOST = '127.0.0.1'
const client = new net.Socket()
client.setTimeout(1000)
let windowSize = 1
let sentPackets = 0
client.on('error', () => {
console.log('Finishing connection...')
process.exit()
})
client.connect(PORT, HOST, () =>
console.log('Connected to ' + HOST + ':' + PORT)
)
client.on('connect', () => {
sendPackets()
})
client.on('data', data => {
sentPackets++
if (sentPackets >= windowSize) {
windowSize *= 2
sentPackets = 0
sendPackets()
}
})
const sendPackets = () => {
for (let i = 0; i < windowSize; i++) {
const message = (i + 1).toString()
client.write(message, err => {
if (err) console.log(err)
})
}
}
client.on('timeout', () => {
windowSize /= 2
sentPackets = 0
sendPackets()
})
服务器代码:
const net = require('net')
const PORT = 8550
const HOST = '127.0.0.1'
const server = net.createServer()
server.on('error', err => console.log(error.toString()))
server.listen(PORT, HOST, () =>
console.log('Servidor listening to ' + HOST + ':' + PORT)
)
server.on('connection', socket => {
socket.on('data', data => {
console.log('Received: ' + data.toString())
socket.write(data)
})
socket.on('error', err => {
console.log(err.toString())
})
})
我知道它收集数据包是因为服务器的以下输出:
收到:1
收到:1
收到:2
收到:1
收到:234
然后它遵循相同的顺序。
【问题讨论】:
-
TCP 连接通常被认为是来自服务器端和客户端的流(下面它确实使用 IP 数据包)。为了分隔更高级别/应用程序级别的数据包,您可以使用一个标头来指示每个数据包的长度,或者使用某种分隔符。你可以看看stackoverflow.com/questions/22414353/… 来获得灵感,这似乎有点相同的挑战。
-
使用 TCP,您无法直接控制您发送的数据如何分组到数据包中或确切地如何传递。如果您需要将其分离成某种类似的单元,那么您必须在应用程序级别执行此操作,并在数据中进行某种划分,您可以在交付时对其进行分类,或者使用 TCP 之上的协议(如 webSocket)或为你做的 socket.io。
-
仅供参考,对于发送数据,TCP 有一个内置的延迟过程,当您发送一小段数据时,它会等待很短的时间来查看是否还有更多数据,因此 TDP 可以将它们组合成一个普通的数据包。您可以在 nodejs 中使用 socket.setNoDelay() 禁用它。
-
但是,即使您使用
setNoDelay(),您也不能指望数据包到达的部分与您发送它们的部分完全相同。这就是 TCP。 TCP 允许将小块数据合并成一个更大的数据包(这通常会提高效率)。