javascript - 获取有关数据响应的 TCP 套接字特定数据
问题描述
我写了以下函数:
let responses = {}
let socks = {}
module.ping = function (port, address) {
//console.log(`Ping function was called - ${address} ${port}`)
if (socks[`${address}:${port}`]) {
//console.log("Using existing socket")
responses[`${address}:${port}`] = false
sock = socks[`${address}:${port}`]
sock.write('PING\n')
console.log(`Sent PING to ${address} ${port}`)
}
else {
sock = new net.Socket();
responses[`${address}:${port}`] = false
sock.connect(port, address, async function() {
sock.write('PING\n')
console.log(`Sent PING to ${address} ${port}`)
});
// Response listeners
sock.on('data', function(data) {
clean_data = data.toString().replace(/\n/g, '').replace(/\r/g, '')
console.log(`[${sock.remoteAddress}:${sock.remotePort}] Received ${clean_data}`)
if (clean_data == 'PONG') {
//console.log(`[${sock.remoteAddress}:${sock.remotePort}] Received PONG`)
//sock.end()
//delete socks[`${address}:${port}`]
responses[`${sock.remoteAddress}:${sock.remotePort}`] = true
}
}
});
sock.on('error', function(error) {
if (sock.remoteAddress) {
responses[`${sock.remoteAddress}:${sock.remotePort}`] = false
}
sock.destroy()
delete socks[`${address}:${port}`]
});
// Add to list of sockets
if (sock) {
socks[`${address}:${port}`] = sock
}
}
}
另一方面,我有一个侦听 TCP 服务器,它简单地以“PONG\n”响应。当我尝试单个主机时,我得到了预期的输出:
module.ping(1337, 10.0.0.100)
await delay(5000) // Custom function
module.ping(1337, 10.0.0.100)
发送 PING 到 10.0.0.100 1337
[10.0.0.100:1337] 收到 PONG
发送 PING 到 10.0.0.100 1337
[10.0.0.100:1337] 收到 PONG
但是,当我尝试访问多个主机时:
module.ping(1337, 10.0.0.100)
module.ping(1337, 10.0.0.200)
await delay(5000) // Custom function
module.ping(1337, 10.0.0.100)
module.ping(1337, 10.0.0.200)
发送 PING 到 10.0.0.100 1337
发送 PING 到 10.0.0.200 1337
[10.0.0.200:1337] 收到 PONG
[10.0.0.200:1337] 收到 PONG
发送 PING 到 10.0.0.100 1337
发送 PING 到 10.0.0.200 1337
[10.0.0.200:1337] 收到 PONG
[10.0.0.200:1337] 收到 PONG
在我看来,我添加的“数据”事件侦听器以某种方式绑定到我的代码中的错误地址,但是我看不到在哪里。如果我向列表中添加更多主机,则发送 PING 的最后一个主机是所有 PONG 都被标记为一部分的主机。
解决方案
对于初学者来说,我没有看到sock
变量的声明,这意味着它在一些更高的范围内,并且在正在进行的不同异步操作之间被错误地混淆或打败。
在本地声明该变量,以便每次使用它都是一个单独的变量,并且一个异步操作不会覆盖您用于另一操作的那个。所有变量,不是有意设计为更高范围和共享的,都必须在本地声明。
我不知道这是否是这里唯一的问题,但这是这里的问题。例如,如果您.ping()
连续调用两次并且必须创建两个新套接字,则第二个将sock
在成功之前覆盖变量,.connect()
导致您将 PING 发送到错误的sock
位置,这正是您的诊断日志显示的内容。
推荐阅读
- mysql - 如何在两张桌子之间获得最高收入?
- python - Python - 向下钻取到新行 - 字典中的列表
- javascript - 我试图阻止我的删除图标在应用于“LI”元素时获得删除线功能
- pandas - 将列表字典映射到熊猫 df
- ios - SwiftUI 和 iOS 应用向后兼容
- c# - .NET Core 3.1 中的链式依赖注入
- java - 使用 Fortify 将字段设置为 null 时的 Java Null 取消引用
- macos - 从 NSItemProvider 获取文件名/路径
- python - Python Regex Sentence Finder - 想要忽略“am”
- kubernetes - Kubernetes 容器命令启动一个不停止的 bash