我正在尝试通过 Node.js 对 MariaDB/MySQL 数据包进行分析。我已经得到了几乎所有内容,但是,当数据包大于 ~64K 时,它会被分成更小的数据包。这意味着套接字
"data"
事件将被调用多次,但是,不可能知道服务器何时完成数据生成(除非我解析传入的有效负载并且它生成有效的数据包,这会适得其反) ).
阅读更多相关内容,我意识到 TCP 协议本身具有可以帮助通过
ACK
和 PSH
标志(据我所知,这将是最后发送的数据包)的标志。
所以,如果我从服务器收到 1MB,这意味着我的包将被分成 16 个数据包,每个数据包 64KB,前 15 个数据包只有
ACK
标志,最后一个 ACK
& PSH
。
如何在
net.Socket()
中获取此信息?
在我看来,Node 不允许直接从 TCP 协议本身访问信息,并且像
bytesReaded
、readableLength
或 readableHighWatermark
这样的属性没有对我有帮助的信息。
这是我当前的代码:
private send(write: Buffer, onData: OnDataCallback) {
const buffers: Buffer[] = [];
const rebuild: OnDataCallback = (partial) => {
// Here we read() from Socket the SQL command response from Server:
buffers.push(partial);
// Event must be off() when all data reach: if(...) { ... }
this.socket.off("data", rebuild);
// Then complete data is concat() and submitted to callback:
onData(Buffer.concat(buffers));
};
this.socket.on("data", rebuild);
// Here we write() to Socket a SQL command:
this.socket.write(write);
}
您无法在 NodeJS(或任何其他用户级应用程序)上的
net.Socket
中获取此信息。 TCP 数据包上的标志由内核处理,该内核为消费应用程序(您的节点应用程序)重新组装数据流。 tcp 数据包、标志、序列号等详细信息均仅由内核处理,用户级应用程序无法访问。
您从那里看到的只是一些新数据可用,但您将没有关于它何时到达、以什么顺序到达或是否有例如数据的可靠信息。丢失了重传的包。
要访问数据包级数据,您需要使用堆栈中较低的东西,通常是一个名为
tcpdump
的工具,从内核获取原始数据包详细信息。
此外,
PSH
标志是MariaDB/MySQL使用的一种优化,以确保接收内核更快地将响应的最后一个数据包中发送的数据传递到客户端应用程序,而不是潜在地等待更多数据包到达。您可能不应该依赖此标志的存在来检测回复何时完全发送。为此,你实际上必须解析 MySQL 协议。