gpt4 book ai didi

c++ - 我的 C++ 代码无法处理(一点点)快速数据流量

转载 作者:太空狗 更新时间:2023-10-29 20:59:28 24 4
gpt4 key购买 nike

背景:

我有下面的 C++ 代码,它在端口26009 上监听 UDP 数据包,然后输出接收到的数据包

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{

udpSocket.bind(26009); //the port that GUI listens (26009)
connect(&udpSocket, SIGNAL(readyRead()), this, SLOT(readyRead()));
}


void MainWindow::readyRead(){
QByteArray datagram;
do {
datagram.resize(udpSocket.pendingDatagramSize());
udpSocket.readDatagram(datagram.data(), datagram.size());
} while (udpSocket.hasPendingDatagrams());

qDebug() << "Message: " << datagram;
}

在客户端,这里是unicast 20个udp数据包的C代码:hi0, hi1, ... hi19:

int main(void){
int i;
char msg[5] = {'\0'};
for(i=0; i<20; i++){
snprintf(msg, 4, "hi%d", i);
send_unicast("192.168.5.1", msg, 26009);
memset(msg, 0, sizeof msg);
}
return 0;
}

void send_unicast(char IPaddr[16], char* message, uint16_t destPort){
struct sockaddr_in si_other;
int s, slen = sizeof(si_other);

if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){
fprintf(stderr, "socket() failed - line817\n");
exit(1);
}

memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(destPort);

if (inet_aton(IPaddr, &si_other.sin_addr) == 0) {
fprintf(stderr, "inet_aton() failed - line 825\n");
exit(1);
}

if (sendto(s, message, 512, 0, (struct sockaddr *) &si_other, slen) == -1){
fprintf(stderr, "sendto() failed - line830\n");
exit(1);
}
close(s);
}

我在不同的 Linux 设备上运行 C++(服务器)和 C(客户端)代码。

问题:

C 代码工作正常并生成数据包。我可以在 Wireshark 上看到数据包是在接收端(C++)接收到的。

但是,上面的 C++ 代码无法正确接收(或处理)数据包,代码处理速度太快,我只看到几个输出,例如

hi5
hi14

如果 C 代码(添加 sleep(1))显着降低了传输频率,那么 C++ 代码可以正常输出数据包。

问题:

我使用接收到的 UDP 数据包来更新 GUI (Qt) 上的一些信息。我猜想是 slot 导致了速度变慢,如果我使用 pthread 来监听数据包,代码会处理流量,但是线程需要如何通知主类,所以GUI 可以相应更新吗?

总而言之,您建议如何修改 C++ 代码,使其能够处理快速数据流量并通知 GUI 更新?

最佳答案

在 MainWindow 的 readyRead 函数中,我预计这会成为一个问题:-

QByteArray datagram;
do {
qint64 dSize = udpSocket.pendingDatagramSize();
datagram.resize(dSize);

udpSocket.readDatagram(datagram.data(), dSize);
} while (udpSocket.hasPendingDatagrams());

如果第一个数据包是 8 个字节长,则将 QByteArray 设置为 8 个字节并读取数据。

当读取 8 个字节时,如果收到 6 个字节,第二次围绕该循环您将调用字节数组的调整大小,但这次它将把它从 8 个字节减少到 6 个并读取 6 个字节,丢弃您之前读入的数据。

与其调整 QByteArray 的大小,我建议您将数据附加到它:-

QByteArray datagram;
do
{ datagram.append(udpSocket.pendingDatagramSize());
udpSocket.readDatagram(datagram.data(), datagram.size());
}while (udpSocket.hasPendingDatagrams());

关于c++ - 我的 C++ 代码无法处理(一点点)快速数据流量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24534582/

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