gpt4 book ai didi

c++ - QTcpSocket 和 TCP 填充

转载 作者:可可西里 更新时间:2023-11-01 02:45:08 26 4
gpt4 key购买 nike

美好的一天。

我正在发送一个自定义协议(protocol)以通过 TCP 进行日志记录,如下所示:

Timestamp (uint32_t -> 4 bytes)
Length of message (uint8_t -> 1 byte)
Message (char -> Length of message)

时间戳被转换为 BigEndian 用于传输并且一切正常,除了一个小细节:填充

时间戳是自己发送的,但是我的应用程序(在 Ubuntu 下使用 BSD 套接字)不是只发送时间戳(4 字节),而是自动向消息附加两个字节的填充。

Wireshark 正确识别了这一点并将两个无关的字节标记为填充,但是 QTcpSocket(Qt 5.8、mingw 5.3.0)显然假设这两个额外的字节实际上是有效载荷,这显然弄乱了我的协议(protocol)。

有什么方法可以让我“教”QTcpSocket 忽略填充(就像它应该的那样)或任何方法来摆脱填充?

如果可能的话,我想避免整个“创建一个足够大的缓冲区并在其中预组装整个数据包以便一次性发送出去”的方法。

非常感谢。

因为被问到了,所以用来发送数据的代码是:

return 
C->sendInt(entry.TS) &&
C->send(&entry.LogLen, 1) &&
C->send(&entry.LogMsg, entry.LogLen);

其中 sendInt 被声明为(Src 是参数):

Src = htonl(Src);
return send(&Src, 4);

其中“发送”声明为(SourceLen 是参数):

char *Src = (char *)Source;
while(Len) {
int BCount = ::send(Sock, Src, Len, 0);
if(BCount < 1) return false;
Src += BCount;
Len -= BCount;
}
return true;

::send 是标准的 BSD 发送函数。

读取是通过QTcpSocket完成的:

uint32_t timestamp;
if (Sock.read((char *)&timestamp, sizeof(timestamp)) > 0)
{
uint8_t logLen;
char message[256];
if (Sock.read((char *)&logLen, sizeof(logLen)) > 0 &&
logLen > 0 &&
Sock.read(message, logLen) == logLen
) addToLog(qFromBigEndian(timestamp), message);
}

SockQTcpSocket实例,已经连接到主机,addToLog是处理函数。

还要注意,发送方需要在嵌入式系统上运行,因此不能使用QTcpServer

最佳答案

您的阅读逻辑似乎不正确。你有...

uint32_t timestamp;
if (Sock.read((char *)&timestamp, sizeof(timestamp)) > 0)
{
uint8_t logLen;
char message[256];
if (Sock.read((char *)&logLen, sizeof(logLen)) > 0 &&
logLen > 0 &&
Sock.read(message, logLen) == logLen
) addToLog(qFromBigEndian(timestamp), message);
}

来自 QTcpSocket::read(data, MaxSize) 的文档它...

Reads at most maxSize bytes from the device into data, and returns the number of bytes read

如果您对 Sock.read 的调用之一读取了部分数据怎么办?您实际上是丢弃了该数据,而不是将其缓冲以供下次重用。

假设您有一个适当范围的QByteArray...

QByteArray data;

你的阅读逻辑应该更符合......

/*
* Append all available data to `data'.
*/
data.append(Sock.readAll());

/*
* Now repeatedly read/trim messages from data until
* we have no further complete messages.
*/
while (contains_complete_log_message(data)) {
auto message = read_message_from_data(data);
data = data.right(data.size() - message.size());
}

/*
* At this point `data' may be non-empty but doesn't
* contain enough data for a complete message.
*/

关于c++ - QTcpSocket 和 TCP 填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45074110/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com