|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
UDP 协议是开放式,无连接,不可靠的传输层通信协议,但它收发数据的速度相对于 TCP 快很多,常用在传输音视频等数据量非常大的场合。+ o* X7 ^7 g+ x6 f, U* w) L! w+ g2 L
udp 网络编程只需要使用一个类 QUdpSocket。7 e( V+ N* ^& s4 G8 T5 u, j/ |
# Q1 a* Z6 O, m4 v y" Y6 a& H6 |本实验中对 QUdpSocket 的基本使用:: { c; h, ~0 D# `: y' a
1.创建 QUdpSocket 对象。
. @ X; o v; C( c( V+ g' j1 O2.绑定端口号
4 V. D0 z2 s/ t: Q* ]; i3.数据到来触发 readyRead()信号。
- d$ R3 ]' V3 d) d, q) a8 n' Y" V( I4.读取发送数据。
8 ]4 w# i5 L# `) h9 T5.关闭。. j! T9 F. A5 R* F7 N' o. Z
具体步骤:
, |. k3 L! D& M+ v. T/ b步骤一:组装 ui 界面,和 TCP 章节搭建 UI 界面方法一致。
& n9 ?8 Z" V6 x
% V5 z+ B' n; L- n- A
步骤二:编写代码9 Y4 h, [! h1 X2 _! [! ]& d
1.创建 QUdpSocket 对象,使用 bind 函数绑定端口号和套接字,数据报到来后会发出信 号
( V- O( o z/ O(),在绑定的槽函数内去读取数据。
, d6 U* S7 p* v6 O* b+ @2.读取数据,数据到来 hasPendingDatagrams()返回 true,再用 pendingDatagramSize()获取数据报的长度,如果数据没有被读取
7 L0 k+ Y" h6 U8 l% B+ [完,hasPendingDatagrams()就会返回 true,直至数据都被读取完。
7 {4 _; l' G/ z1 b/ H+ R; WreadDatagram(data,size);
! V5 b$ K8 a$ U7 P" m参数 data 为读取的数据,size 为数据长度。4 C) X% n( [! `8 b
3.发送数据,使用 writeDatagram 函数,( X) {, p& c |( j
writeDatagram(const char *data, qint64 len, const QHostAddress &host, quint16 port);3 }9 T- p. N/ ^
Data:发送的数据。
' u0 s& t: S. H- S3 U4 K1 lLen:发送的数据长度。9 {: V' M o @$ q6 j# \
Host:目标 IP 地址。
, f& \$ x9 d2 U* F" gPort:目标端口号。) h' I8 m0 p/ [/ E6 A
4.关闭 socket 套接字。
/ ]& x2 `) Z/ Z' w8 J' v- }. y代码如下:7 T/ p- ~# V. M2 U
- udp.h
g+ Z; B" C5 ? - #include <QMainWindow>( v) u) J' J% }% L: U
- #include <QUdpSocket>) c {8 M# J: o$ [, z4 O
- namespace Ui {
6 Z2 L& g2 x& R; } - class Udp;5 y) v/ |! x' q) _. F6 B. O2 O: k
- }
9 C; r6 l+ B6 Y- `& [7 M/ }, Y - class Udp : public QMainWindow+ k1 d" M# Q9 J% w2 `1 S
- {
' k* {6 I9 b+ p4 `7 f7 E/ E3 O - Q_OBJECT
* y0 R/ l5 v8 }0 o: K - public:
' @, p0 l( n% I1 k/ f& \ - explicit Udp(QWidget *parent = 0); ~Udp();& `: C5 L8 t6 u, x3 e/ B
- QUdpSocket * udpSocket;
+ `/ b: Z+ c5 u) _% r( ` - private slots:: V" M* E" M: n& H8 M2 o1 a
- void on_pushButton_clicked();; P( U$ C+ `$ O* {6 t0 [( b
- void readyRead_Slot(void);6 s; d8 h1 R; E1 g9 C
- void on_pushButton_3_clicked();" T& ?$ ?- `* H# y
- void on_pushButton_2_clicked();4 e/ [ ]8 W: u, f, N
- private:1 G9 M& S K' E" Y
- Ui::Udp *ui;7 T; R7 @! `' U" v, e7 |
- };0 j0 v2 k! U9 G: U
- udp.cpp:; d( T) K' p* e1 X' t. I+ ?
- Udp::Udp(QWidget *parent) :
- M9 E( f3 w. w" N5 l/ ^ - QMainWindow(parent), ui(new Ui::Udp)5 H( m& ~- h: Z: J: K
- {
) |3 t& w ?* y3 I& F6 K8 p0 l4 L) P9 O - ui->setupUi(this);, m! G* Q9 y, Y {% L9 O1 ?5 g
- udpSocket = new QUdpSocket(this);
/ Y- G( `5 G5 Y+ l" w0 ^ - }
2 x) v# }* X4 P9 y - Udp::~Udp()
. G7 y* {( A0 E8 w! \ - {
$ `" _6 Y" c, L; F% P6 K - delete ui;
: ?/ A% A/ { t9 a6 W: E+ _4 {4 [ - }
& y1 G; t7 e6 I5 z3 H+ b - /*
9 m/ S% ^9 q, ^4 Q - * 打开按钮8 s) ]. s( M( t- I; F- n) m$ x+ h6 T
- */0 v! l5 \7 G2 x- q/ D" g: ~& Y
- void Udp::on_pushButton_clicked()( F- o: g0 V9 G; ^2 G
- {
' o( _1 G; Y, Q - //绑定本端口的端口号
; r" v$ z0 z; w" h - if(udpSocket->bind(ui->cliEdit->text().toUInt()) == true){) F9 R1 [/ d* N
- QMessageBox::information(this,"提示","成功");8 u* L, i0 L& l3 m
- }else{. m2 S$ _; G5 K
- QMessageBox::information(this,"提示","失败");
9 \: j7 |4 M3 Q# j - }
! s0 x& i! q3 ] - //绑定数据信号和槽函数
! i/ T" `" z$ Q - connect(udpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));6 G2 ~# |# Y! u! l/ _6 c- S
- }$ c' n& v, \* {0 @7 d" ~1 D4 X# E9 x
- /*8 ]* N3 a1 h" m! d, @
- *读取数据槽函数
; A3 h: Q4 Z$ B I1 C! A; h1 o - */ f! b8 M* a# T9 U
- void Udp::readyRead_Slot()
$ N' T4 M5 k& g* {; G) k N- M - {% P- c" o3 h4 f' k e
- QString buf;
0 R; A% O' r# E1 B3 W! V- M - QByteArray array;7 x% L8 x; K1 \3 C2 b
- //hasPendingDatagrams()返回 true 时表示至少有一个数据报在等待被读取
( m: p) Y g- a( n( e8 C: n - while(udpSocket->hasPendingDatagrams()){7 y2 I7 w V; g7 x' }! `
- //获取数据; m) [5 }% c1 m! [
- array.resize(udpSocket->pendingDatagramSize());
: o, |* ^" ^/ X - udpSocket->readDatagram(array.data(),array.size());3 {! x( r2 ?0 Y# _3 I7 A( Z B
- buf = array.data();
/ c$ f* J2 G. r - ui->recvEdit->appendPlainText(buf);* j! X2 T7 e0 t9 G: M4 t
- }1 b1 v' p& Z6 k' x. ?( a% \9 w
- }
R. p& [4 e/ n. `; I3 r - /*7 Z) {& P3 v, [3 T
- * 发送数据( M3 _# Z- ?3 H
- */
- S% J9 H' C1 {9 {1 A2 e - void Udp::on_pushButton_3_clicked()
0 ] I* d+ a1 T0 ]3 l - {: T& E* n7 r2 p: s
- quint16 port;
# w9 b0 x6 [- V$ l - QString sendBuff;
6 G- d m1 r: M, | - QHostAddress address;3 G& l' z) O9 D3 B7 q3 d
- address.setAddress(ui->ipEdit->text());//目标机地址
5 N5 |. \) k# F. {" d9 G - port = ui->portEdit->text().toInt();//目标机端口号
6 R+ Z1 O8 q" Z; s2 V8 \ - sendBuff = ui->sendEdit->text();//发送的数据8 ^$ O8 p1 n8 ^1 A% u5 v& |
- //发送 J: w$ e5 r( N
- udpSocket->writeDatagram(sendBuff.toLocal8Bit().data(),sendBuff.length(),address,port);
0 M' @0 z' y& ~ - }8 J" Z% N5 r% A0 |- F
- /*
, } e7 G8 f: m4 q0 c - *关闭8 T, O3 A3 i; X. u' |* c# v
- */
2 T- l) y5 u( ]# c - void Udp::on_pushButton_2_clicked(); A4 A: L' b' ]4 d. y
- {& `. v8 M- `& i; @- r$ _
- udpSocket->close();; Z3 f: L! y2 O
- }
复制代码
: o( n: X5 k5 n4 k7 S1 I C1 ^) e4 M8 x% T7 F) ?" j6 r# @9 _
|
|