UDP入門學習I

目標:實現一個界面發送和接收
注意:要在工程名的右鍵菜單中勾選NetWork library,並且在頭文件中加上#include <QtNetwork>
這裏寫圖片描述
1. UDP套接字
UDP套接字就是一個IP地址加一個port端口,因爲我們要傳輸數據,就要知道往哪個機子上傳送,而IP地址確定了一臺主機,但是這臺機子上可能運行着各種各樣的網絡程序,我們要往哪個程序中發送呢?這時就要使用一個端口來指定UDP程序。在使用前不需要進行連接。TCP協議與電話通信相似,而UDP協議則與郵件通信相似:你寄包裹或信件時不需要進行”連接”,但是你得爲每個包裹和信件指定目的地址。類似的,每條信息(即數據報文,datagram)負載了自己的地址信息,並與其他信息相互獨立。在接收信息時,UDP套接字扮演的角色就像是一個信箱,從不同地址發送來的信件和包裹都可以放到裏面。一旦被創建,UDP套接字就可以用來連續地向不同的地址發送信息,或從任何地址接收信息。
  UDP套接字與TCP套接字的另一個不同點在於他們對信息邊界的處理方式不同:UDP套接字將保留邊界信息。這個特性使應用程序在接受信息時,從某些方面來說比使用TCP套接字更簡單。
  最後一個不同點是,UDP協議所提供的端到端傳輸服務是盡力而爲(best-effort)的,即UDP套接字將儘可能地傳送信息,但並不保證信息一定能成功到達目的地址,而且信息到達的順序與其發送順序不一定一致(就像通過郵政部門寄信一樣)。因此,使用了UDP套接字的程序必須準備好處理信息的丟失和重排。
2. 目標界面
這裏寫圖片描述

  1. 頭文件裏面的聲明
private:
    Ui::UDPMsgClass ui;
    QUdpSocket *udp_socket_rx;//接收端套接字
    QUdpSocket *udp_socket_tx;//發送端套接字
    QHostAddress Ip_tx;//發送端IP
    int Port_tx;//發送端Port

private slots:
    void on_btn_cfg_clicked();//配置按鈕函數
    void on_btn_tx_clicked();//發送按鈕函數
    void on_btn_clear_clicked();//清除按鈕函數
    void rx_udp();//接收處理函數
  1. c文件的編寫
    首先,在構造函數裏面進行信號與槽函數的綁定。
    udp_socket_rx = new QUdpSocket(this);
    udp_socket_tx = new QUdpSocket(this);
    connect(ui.Btn_tx, SIGNAL(clicked()), this, SLOT(on_btn_tx_clicked()) );
    connect(ui.Btn_cfg, SIGNAL(clicked()), this, SLOT(on_btn_cfg_clicked()) );
    connect(ui.Btn_clear, SIGNAL(clicked()), this, SLOT(on_btn_clear_clicked()) );
    connect(udp_socket_rx, SIGNAL(readyRead()), this, SLOT(rx_udp()));//當接收套接字接收到數據時,轉到rx_udp()函數進行處理
    ui.Btn_tx->setEnabled(false);//設置爲不可按下
然後,再實現各個槽函數。
void UDPMsg::on_btn_clear_clicked(){//清屏函數
    ui.Bro_rx->clear();
    ui.Bro_tx->clear();
}
void UDPMsg::on_btn_cfg_clicked(){//配置函數
    bool ok;
    int Port_rx = 0;
    Ip_tx = QHostAddress(ui.Line_TxIP->text());
    Port_tx = ui.Line_TxPort->text().toInt(&ok);

    Port_rx = ui.Line_RxPort->text().toInt(&ok);
    udp_socket_rx->bind(Port_rx,QHostAddress::ShareAddress);//接收的套接字綁定相應的Port和IP


    ui.Btn_tx->setEnabled(true);//激活發送按鈕
}
void UDPMsg::rx_udp(){//接收處理函數
    while (udp_socket_rx->hasPendingDatagrams())//當接收到報文數據時
    {
        QByteArray datagram;//因爲傳送來的數據類型是未知,所以用Bytearray
        datagram.resize(udp_socket_rx->pendingDatagramSize());//datagram的數據大小取決於接收到的數據

        udp_socket_rx->readDatagram(datagram.data(), datagram.size());//讀取數據  
        ui.Bro_rx->append(datagram);//將報文顯示到接收框
    }
}
void UDPMsg::on_btn_tx_clicked(){//發送按鈕處理函數
    QByteArray datagram = ui.Bro_tx->toPlainText().toAscii();
    udp_socket_tx->writeDatagram(datagram, datagram.size(), Ip_tx, Port_tx);
}

注:因爲是實現的同一個界面既發送又接收數據,所以其UDP端口號也要一樣的,這樣才能夠正常的接收到發送的數據

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章