0. UDP概述
UDP通信时轻量的、不可靠的、面向数据报、无连接的协议,用于对可靠性要求不高的场合。与TCP通信不同,两个程序之间进行UDP通信无需预先建立持久的socket连接,UDP每次发送数据报都需要指定目标地址和端口。
UDP消息传输有单播、广播和组播三种模式。
1. QT准备工作
.pro文件添加 QT += network
.h和.cpp文件添加#include <QtNetwork>
QUdpSocket *udpSocket;
udpSocket = new QUdpSocket();
connect(udpSocket,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));
2. 第一种通信 单播
cpp
//绑定本地端口号 连接
bool ok = udpSocket->bind(Local_Port);
//绑定远端的端口和IP 连接
//QHostAddress Target_IP = QHostAddress(Target_IP_1);
//quint16 Target_Port = Target_Port_1.toUShort();
udpSocket->connectToHost(Target_IP,Target_Port);
//直接发送数据 而且只能给指定的端口和IP发送
udpSocket->write("connectToHost");
//断开两种都可以
udpSocket->disconnectFromHost();
//udpSocket->abort();
//槽函数
void onSocketReadyRead()
{
Return_QByteArray.clear();
//读取收到的数据报
while(udpSocket->hasPendingDatagrams())
{
Return_QByteArray = udpSocket->readAll();
//Return_QByteArray = udpSocket->readLine();//数据中有/r/n或则/r或者/n系统崩溃
}
}
3.第二种通信 单播
cpp
//绑定本地端口号 连接
bool ok = udpSocket->bind(Local_Port);
//发出数据报 带远端的端口和IP 连接
//变量是QString Target_Port_1,Send_data_str
//QHostAddress Target_IP = QHostAddress(Target_IP_1);
//quint16 Target_Port = Target_Port_1.toUShort();
udpSocket->writeDatagram(Send_data_str.toLatin1(),Target_IP,Target_Port);
//断开
udpSocket->abort();
//槽函数
void onSocketReadyRead()
{
Return_QByteArray.clear();
//读取收到的数据报
while(udpSocket->hasPendingDatagrams())
{
Return_QByteArray.resize(udpSocket->pendingDatagramSize());
QHostAddress peerAddr;
quint16 peerPort;
udpSocket->readDatagram(Return_QByteArray.data(),Return_QByteArray.size(),&peerAddr,&peerPort);
}
}
4.广播
cpp
//绑定本地端口号 连接
bool ok = udpSocket->bind(Local_Port);
//广播
udpSocket->writeDatagram(str,QHostAddress::Broadcast,targetPort);
//槽函数
void onSocketReadyRead()
{
Return_QByteArray.clear();
//读取收到的数据报
while(udpSocket->hasPendingDatagrams())
{
Return_QByteArray.resize(udpSocket->pendingDatagramSize());
QHostAddress peerAddr;
quint16 peerPort;
udpSocket->readDatagram(Return_QByteArray.data(),Return_QByteArray.size(),&peerAddr,&peerPort);
}
}
5. Flush()函数
- 不需要 flush()
原因:
- UDP 是数据报直接发内核缓冲区,write() 调用完立刻交给系统网络栈,没有 Qt 内部缓冲需要刷出去;
- flush() 是给 QFile、QTcpSocket 阻塞模式 用的,用来把内部缓存强制落盘 / 发出去;QUdpSocket 根本不靠流式缓冲,所以 flush 对 UDP 无效、多余。