I wrote a program for transmitting pictures via UDP in Qt. I encountered a problem that QUdpSocket does not accept an image larger than 50 kb. I decided to split the image into several datagrams and send it. As a result, the required number of datagrams is sent, and, as I understand it, only the first two are received. Why is this happening and do you have other options to solve the problem?
main.cpp:
#include <QApplication>
#include "udp_server.h"
#include "udp_client.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
UDP_Server server(2323);
UDP_Client client(2323);
server.show();
client.show();
return a.exec();
}
udp_server.h and udp_server.cpp:
#ifndef UDP_SERVER_H
#define UDP_SERVER_H
#include <QWidget>
#include <QUdpSocket>
#include <QBoxLayout>
#include <QLabel>
#include <QBuffer>
#include <QFile>
class UDP_Server : public QWidget
{
Q_OBJECT
public:
explicit UDP_Server(int port, QWidget *parent = nullptr);
private:
QUdpSocket* socket;
QLabel* showLabel;
private slots:
void slotProcessDatagrams();
};
#endif // UDP_SERVER_H
//================================
#include "udp_server.h"
UDP_Server::UDP_Server(int port, QWidget *parent)
: QWidget{parent}
{
setWindowTitle("SERVER");
socket = new QUdpSocket(this);
socket->bind(QHostAddress::LocalHost, port);
connect(socket, SIGNAL(readyRead()), SLOT(slotProcessDatagrams()));
showLabel = new QLabel;
QVBoxLayout* box = new QVBoxLayout;
box->addWidget(showLabel);
setLayout(box);
}
void UDP_Server::slotProcessDatagrams() {
QByteArray datagram;
QPixmap frame;
while (socket->hasPendingDatagrams()) {
QByteArray receivedData;
receivedData.resize(socket->pendingDatagramSize());
socket->readDatagram(receivedData.data(), receivedData.size());
datagram.append(receivedData);
qDebug() << "read: " << receivedData.size();
}
if (frame.loadFromData(datagram, "PNG")) {
showLabel->setPixmap(frame);
} else {
qDebug() << "Failed to read frame";
}
}
udp_client.h and udp_client.cpp:
#ifndef UDP_CLIENT_H
#define UDP_CLIENT_H
#include <QWidget>
#include <QUdpSocket>
#include <QPushButton>
#include <QBoxLayout>
#include <QTextEdit>
#include <QBuffer>
#include <QFile>
class UDP_Client : public QWidget
{
Q_OBJECT
public:
explicit UDP_Client(int port, QWidget *parent = nullptr);
private:
QUdpSocket* socket;
int port;
private slots:
void slotSendDatagram();
};
#endif // UDP_CLIENT_H
//================
#include "udp_client.h"
UDP_Client::UDP_Client(int port, QWidget *parent)
: QWidget{parent}, port(port)
{
setWindowTitle("CLIENT");
socket = new QUdpSocket(this);
QPushButton* btn = new QPushButton("Send");
connect(btn, SIGNAL(clicked()), SLOT(slotSendDatagram()));
QVBoxLayout* box = new QVBoxLayout;
box->addWidget(btn);
setLayout(box);
}
const int UDP_DATAGRAM_SIZE = 50000;
void UDP_Client::slotSendDatagram() {
QFile file("path/to/image");
if (file.open(QIODevice::ReadOnly)) {
while (!file.atEnd()) {
QByteArray datagram = file.read(UDP_DATAGRAM_SIZE);
socket->writeDatagram(datagram, QHostAddress::LocalHost, port);
qDebug() << "send: " << datagram.size();
}
file.close();
}
}
output from qDebug():
send: 50000
send: 50000
send: 50000
send: 24753
read: 50000
read: 50000
Failed to read frame
Also, if you try to send a picture weighing less than 50 kb or more than 50 kb but less than 100 kb (to make 2 datagrams), then everything is sent and received normally