QT Socket communication one
- UDP is a lightweight socket communication with functions such as broadcasting and multicasting. UDP transmits data through data packets, without the problem of sub-packaging and grouping, which is convenient and quick. This article introduces an example of QT UDP communication.
QUdpSocket class
include
- To use QT's QUdpSocket class, you need to add in the pro file:
QT += network
- Add in .h
#include <QUdpSocket>
#include <QtNetwork>
Official example
//服务端绑定端口,能够收到固定端口的广播信号。
void Server::initSocket()
{
udpSocket = new QUdpSocket(this); //创建对象
udpSocket->bind(QHostAddress::LocalHost, 7755); //绑定端口
//当UDP收到消息后,会发送readyRead信号,
//连接成功有 connected,断开连接有,disconnected信号。
connect(udpSocket, SIGNAL(readyRead()),
this, SLOT(readPendingDatagrams()));
}
void Server::readPendingDatagrams()
{
while (udpSocket->hasPendingDatagrams()) {
//从缓冲区中读取数据,
QNetworkDatagram datagram = udpSocket->receiveDatagram();
//处理数据。
processTheDatagram(datagram);
}
}
In the official instance
Broadcast and receive custom structure/message body
Informed body
Add msg_type.h file and declare the structure. For example as follows
typedef struct
{
unsigned int send_id; // 发送方的ID(网络的IP、SRIO的ID)
unsigned int recv_id; // 接收方的ID(网络的IP、SRIO的ID)
unsigned int msg_type : 8; // 消息类型
unsigned int len : 24; // 消息长度,字节数
unsigned int conn_type: 8; // 连接类型,TCP、UDP等
unsigned int pkg_num : 8; // 总的包数(用于组包传输)
unsigned int pkg_idx : 8; // 子包索引(用于组包传输),从1计数
unsigned int rsvd : 8; // 保留位
unsigned int check_sum; // 校验位
char* load; // 消息体地址
} DispCtrlMsg;
broadcast
/**
* @brief Widget::on_UDPButton_clicked
* 从6000端口广播消息
*/
void MainWindow::on_udpBroadButton_clicked()
{
quint16 targetPort = ui->lineEdit_udpport->text().toUShort();
DispCtrlMsg *sendMsg = new DispCtrlMsg();
sendMsg->send_id = QHostAddress(ui->combox_tcpip->currentText()).toIPv4Address();
sendMsg->msg_type = 0x10;
sendMsg->conn_type = UDPCONNECTION;
sendMsg->len = headLength;
sendMsg->check_sum = sendMsg->send_id + sendMsg->msg_type + sendMsg->conn_type;
QByteArray str;
str.append((char*)sendMsg, headLength);
//headLength = sizeof(DispCtrlMsg)- sizeof(char*)
//不发送char*部分的数据。
udpSocket->writeDatagram(str, QHostAddress::Broadcast, targetPort);
delete sendMsg;
}
receive
- The receiving end needs to bind ports to accept broadcast packets. After binding the port, if there is a broadcast packet, or the udp connection will send the corresponding signal. The trigger signal of onUDPReadyRead() is: readyRead() (this signal is inherited from QIODevice).
quint16 port = 6000;
udpSocket->bind(port);
receive
void Widget::onUDPReadyRead()
{
while (udpSocket->hasPendingDatagrams()) {
QHostAddress peerAddr;
quint16 peerPort;
QByteArray recvMsg;
DispCtrlMsg msgHead;
udpSocket->readDatagram((char*)&msgHead, sizeof(msgHead));
qDebug() << QString::number(msgHead.msg_type,16).toUpper();
qDebug() << msgHead.send_id;
serverIP = msgHead.send_id;
onConnected();
}
}