我正在尝试在 Linux 上使用 Qt6 解决网络错误,其中 aQUdpSocket
没有接收到它应该接收的所有数据。虽然对于少量数据(以 kB 为单位),所有字节都可以通过,但较大的数据报(~384 kB)从末尾被剪掉。在这种情况下,我测量到在数据流的末尾丢失了大约 4kB。
为了解决基本问题,我有:
尝试将物理以太网连接从本地路由器更改为具有静态 IP 的点对点链接。
通过 Wireshark 确认所有数据(包括剪辑位)都进入了我的 Linux 套接字。并通过日志消息确认并非所有数据都从
QUdpSocket
.尝试使用
setReadBufferSize()
和增加接收缓冲区大小setSocketOption(QAbstractSocket::ReceiveBufferSizeSocketOption, ...)
验证当我使用
QNetworkDatagram
而不是缓冲区以及使用QUdpSocket
's 信号而不是同步接收模式时会出现相同的错误。
这是我展示该错误的最小示例代码:
// Configuration constants:
static constexpr int TIMEOUT_MS = 250;
static constexpr int LOCAL_PORT = 1234;
static constexpr qsizetype READ_BUFFER_SIZE = 8388608; // bytes, more than enough for "small" as well as "large" data bursts
// Open a socket
auto socket = new QUdpSocket();
socket->bind(LOCAL_PORT);
if (socket->state() != QAbstractSocket::BoundState) {
qDebug() << "Timeout!";
return;
}
socket->setReadBufferSize(READ_BUFFER_SIZE); // according to Qt docs, this has no effect for QUdpSocket
socket->setSocketOption(QAbstractSocket::ReceiveBufferSizeSocketOption, READ_BUFFER_SIZE);
// Synchronously read from the socket
std::vector<char> data_buffer{};
forever {
if (!socket->hasPendingDatagrams()) {
waitForReadyRead(TIMEOUT_MS);
}
if (!socket->hasPendingDatagrams()) {
qDebug() << "Timeout!";
continue;
}
const qint64 recv_size = socket->pendingDatagramSize();
data_buffer.resize(recv_size);
const qint64 n_received{socket->readDatagram(data_buffer.data(), data_buffer.size())};
if (n_received < 0) {
qDebug() << "Error:" << socket->error();
continue;
} else if (n_received != recv_size) {
qDebug() << "Error: received != ready size, " << n_received << "!=" << recv_size;
continue;
}
// This function just prints binary data in hex:
printData(data_buffer.data(), data_buffer.size());
}
socket->close(); // never reached