[轉]QUdpSocket收發信息


文章轉自:https://www.cnblogs.com/techiel/p/7978049.html

代碼轉自:https://blog.csdn.net/we1583004we/article/details/79188305

1. QNetworkDatagram

qt網絡報文,可用其建立一個通訊內容包括目標ip、端口號、數據內容。同時接收到的信息也未此類型,可以訪問接收數據的長度、發送者的ip及端口等信息

QUdpSocket

有Qt提供的udp通訊的類,詳細介紹請見官方文檔

2. 客戶端

注意pro文件要包含QT += network

  1. #include <QHostAddress>
  2. #include <QUdpSocket>
  3. QUdpSocket *m_socket=new QUdpSocket;
  4. m_socket.writeDatagram(msg, QHostAddress::localhost, 8000);

qudpsocket對於發送數據報文提供了三個重載函數:

  1. qint64 writeDatagram(const char *data, qint64 size, const QHostAddress &address, quint16 port)
  2. qint64 writeDatagram(const QNetworkDatagram &datagram)
  3. qint64 writeDatagram(const QByteArray &datagram, const QHostAddress &host, quint16 port)

上面的范例使用的是第三種類型,也可以自行建立QNetworkDatagram對象,修改好內容后直接調用writeDatagram

3. 服務端

服務端與客戶端類似,需要先綁定端口“bind”,此函數在QAbstractSocket類中提供

  1. bool bind(const QHostAddress &address, quint16 port = 0, BindMode mode = DefaultForPlatform)
  2. bool bind(quint16 port = 0, BindMode mode = DefaultForPlatform)

具體使用方式:

  1. m_socket = new QUdpSocket;
  2. m_socket->bind(QHostAddress::localhost, 8000);
  3. connect(m_socket, SIGNAL(readyRead()), this, SLOT(receive()));

綁定端口以后,需要將此socket的readyread信號與自定義槽函數連接,當服務端收到消息時會觸發此信號。

4. 消息收發

由於udp與tcp不同,不需要三次握手建立連接,所以並不會在連接之后記錄當前socket。

發送消息在客戶端中已經提供示例

接收消息需要使用Qudpsocket提供以下函數:

  1. qint64 pendingDatagramSize(const
  2. qint64 readDatagram(char *data, qint64 maxSize, QHostAddress *address = Q_NULLPTR, quint16 *port = Q_NULLPTR)
  3. QNetworkDatagram receiveDatagram(qint64 maxSize = -1)

當readyRead信號觸發時,可直接通過receiveDatagram函數獲取消息報文對象,其內存儲消息的發送ip、端口、消息內容等所有信息。

也可以通過pendingDatagramSize判斷消息長度,然后通過readDatagram獲取消息內容。

在readyRead槽函數中可以先調用QUdpSocket::hasPendingDatagrams判斷當前是否有需要讀取的消息,若有消息再進行pendingDatagramSize獲取需要讀取的大小

 

****************************************************************************************************************************************************

客戶端

udpclient.cpp

#include "udpclient.h"
#include "ui_udpclient.h"
#include <QTextCodec>
#include <QDebug>
UdpClient::UdpClient(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::UdpClient)
{
    ui->setupUi(this);
    //QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
    clientudp=new QUdpSocket(this);
    clientudp->bind(6000,QUdpSocket::ShareAddress);//綁定讀數據端口(監聽端口),允許其他服務綁定到此端口
    connect(clientudp,SIGNAL(readyRead()),this,SLOT(recv()));
}
 
UdpClient::~UdpClient()
{
    delete ui;
}
 
void UdpClient::on_pushButton_clicked()
{
//    QHostAddress serverip;
//    serverip.setAddress(QString("192.168.0.7"));//這是人為指定ip地址的方法
    clientudp->writeDatagram(QVariant(ui->textEdit_write->toPlainText()).toByteArray(),QHostAddress::LocalHost,5000);//向5000端口寫數據
}
void UdpClient::recv()
{
    while(clientudp->hasPendingDatagrams())
    {
        QByteArray data;
        data.resize(clientudp->pendingDatagramSize());
        clientudp->readDatagram(data.data(),data.size());
        ui->textEdit_show->setText(QVariant(data).toString());
    }
}
//注意,監聽與發送的端口可以相同也可以不同,它們相對獨立,就像有名管道

 

服務端代碼:

udpserver.cpp

#include "udpserver.h"
#include "ui_udpserver.h"
#include <QVariant>
UdpServer::UdpServer(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::UdpServer)
{
    ui->setupUi(this);
    serverudp=new QUdpSocket(this);
    serverudp->bind(5000,QUdpSocket::ShareAddress);//綁定讀數據端口(監聽端口),允許其他服務綁定到此端口
    connect(serverudp,SIGNAL(readyRead()),this,SLOT(recv()));
}
 
UdpServer::~UdpServer()
{
    delete ui;
}
void UdpServer::recv()
{
    while(serverudp->hasPendingDatagrams())
    {
        QByteArray data;
        data.resize(serverudp->pendingDatagramSize());
        serverudp->readDatagram(data.data(),data.size());//
        ui->textEdit_show->clear();
        ui->textEdit_show->setText(QVariant(data).toString());
    }
}
 
void UdpServer::on_pushButton_clicked()
{
    //    QHostAddress serverip;
    //    serverip.setAddress(QString("192.168.0.7"));//這是人為指定ip地址的方法
    serverudp->writeDatagram(QVariant(ui->textEdit_write->toPlainText()).toByteArray(),QHostAddress::LocalHost,6000);//向6000端口寫數據
}
//注意,監聽與發送的端口可以相同也可以不同,它們相對獨立,就像有名管道

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM