|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
UDP 协议是开放式,无连接,不可靠的传输层通信协议,但它收发数据的速度相对于 TCP 快很多,常用在传输音视频等数据量非常大的场合。0 [" x+ ]1 O9 S
udp 网络编程只需要使用一个类 QUdpSocket。
, ^1 I" m0 A$ \3 A6 ?3 ]
+ E- C0 h6 @* Z/ D本实验中对 QUdpSocket 的基本使用:
d. y/ S1 t9 _0 ~8 l8 I1.创建 QUdpSocket 对象。" k7 G% W l5 Q8 Y
2.绑定端口号) [5 S* Z, H* ~+ U+ j( ]; U! C M
3.数据到来触发 readyRead()信号。
' p& Q1 E+ a6 z% }4.读取发送数据。# H, A- R" c" L8 \
5.关闭。 x4 m9 C2 O4 S
具体步骤:
# m; Q' ?/ u1 k步骤一:组装 ui 界面,和 TCP 章节搭建 UI 界面方法一致。. x3 U1 q9 t4 `( V
3 @2 t& M' C- V0 I0 |4 v6 C步骤二:编写代码# w1 W) d2 v+ H% ^0 u9 Q& ]6 |
1.创建 QUdpSocket 对象,使用 bind 函数绑定端口号和套接字,数据报到来后会发出信 号
, J" N1 C2 E0 y. x2 ~2 x4 `6 D$ k% b(),在绑定的槽函数内去读取数据。
+ J `2 k( c9 C2.读取数据,数据到来 hasPendingDatagrams()返回 true,再用 pendingDatagramSize()获取数据报的长度,如果数据没有被读取8 e* |4 ^: U* Q- k3 p
完,hasPendingDatagrams()就会返回 true,直至数据都被读取完。
+ M. W3 N) w+ a% v7 H9 H& oreadDatagram(data,size);
7 e: j2 ^0 w1 M6 G# Q% [+ a0 J8 k参数 data 为读取的数据,size 为数据长度。8 w' X% p* `6 U6 o# }4 ]1 E
3.发送数据,使用 writeDatagram 函数,
( w; B7 ]$ e- XwriteDatagram(const char *data, qint64 len, const QHostAddress &host, quint16 port);
8 _/ u, ^& d) m( d* kData:发送的数据。% m, i7 m$ q% K: \6 ]; M! V
Len:发送的数据长度。
0 O. S( w: E& V! V" gHost:目标 IP 地址。
5 b- a# z- h/ w. [# ]2 S+ v5 qPort:目标端口号。! G! C# d- w1 _2 t
4.关闭 socket 套接字。
: x1 M# U7 e: `6 q( ?4 }6 G代码如下:
6 L3 j& p6 T4 \+ \% Q/ c. t- udp.h
2 g' n5 Y e7 _2 M) B0 D - #include <QMainWindow>
- i' B# `5 H6 F* ?6 _: k. @ - #include <QUdpSocket>
3 Y2 u: [1 y; K" U - namespace Ui {
% T- M* H4 y: V% S) u - class Udp;) ?6 r( T6 k8 V
- }: w5 m. R) j) f" r3 r
- class Udp : public QMainWindow2 R* Y' ^/ A! a
- {
4 ?: Q" j1 p& D; i; e& Q - Q_OBJECT
5 N$ ~" F# E* N - public:
: x- s! t& ?& X) l6 n - explicit Udp(QWidget *parent = 0); ~Udp();- D; K" i" t. d K# K
- QUdpSocket * udpSocket;
% ]' G" m e/ @' A+ h( T( ? - private slots:
; l; O# i# ^% A+ T, Z) k6 @* v" B - void on_pushButton_clicked();6 V, T3 ?; g1 ^: [& o; @8 _
- void readyRead_Slot(void);0 U1 }2 [. e% ^
- void on_pushButton_3_clicked();+ p3 g* c! u6 U9 K! O
- void on_pushButton_2_clicked();+ P1 L' L7 F" M2 j
- private:# \# D" a# H- b6 m
- Ui::Udp *ui;, V) q$ I+ B+ v: V; L( i
- };/ p% |; @! V" _
- udp.cpp:
t6 Y0 f0 T4 ~3 G1 t+ r - Udp::Udp(QWidget *parent) :1 A+ F" r: f% r8 L$ s# w; c
- QMainWindow(parent), ui(new Ui::Udp)* c+ Y7 p8 j3 m- P8 G7 c& c
- {+ r$ C1 m0 ]+ u& s% R$ u# j
- ui->setupUi(this);) V) X5 \4 w8 C% \; p1 ^' |' Z3 O
- udpSocket = new QUdpSocket(this);7 K. d, G! ~% r, O$ `9 n8 O
- }" q d4 k8 @5 m0 n' s
- Udp::~Udp()4 _# H6 O6 ?; W1 h
- {
9 W Z+ |* T1 F5 U" b - delete ui;
9 `9 _1 E6 J# h7 y - }, _5 s3 H ~9 p6 \: A
- /*1 t" W! V% q/ | Q$ m# C
- * 打开按钮7 i7 s& L/ O" ]
- */* O$ ~% \0 R! Z2 f7 w
- void Udp::on_pushButton_clicked()
# L0 p2 Y) n& k - {
; |4 E# o* g: I i+ c- R% G* f - //绑定本端口的端口号
; H* ~ K$ |! Y4 ~) c: i - if(udpSocket->bind(ui->cliEdit->text().toUInt()) == true){% q" z2 b5 [4 m- q& B" c' ?
- QMessageBox::information(this,"提示","成功");2 A( Y6 u4 _$ Q
- }else{/ q7 f0 x9 M4 N1 f) q% G: ~$ J. ~
- QMessageBox::information(this,"提示","失败");
0 R" w% i9 K' c0 {6 W* K - }6 `0 f# K4 g5 e
- //绑定数据信号和槽函数6 }( Z/ z) Q6 Z8 s; Z
- connect(udpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));9 O2 ?" a1 j. l$ n
- }3 X* x& B- g9 U" D4 A/ ?
- /** A* A8 u" @4 m1 v! ]) O$ K
- *读取数据槽函数
9 I% r4 n2 `8 B4 d# ~ - */
! y- D' C6 @* L) I1 ^ - void Udp::readyRead_Slot()' J/ ?. S0 F2 _' o# e9 g* _
- {3 H) c# R2 K: J& c
- QString buf;( X0 t4 k% j: h9 r: o
- QByteArray array;9 E2 {& h' b- R. C" J
- //hasPendingDatagrams()返回 true 时表示至少有一个数据报在等待被读取9 B) ]5 r, E/ C. C1 c( B
- while(udpSocket->hasPendingDatagrams()){4 A( T T& z8 c! [5 R7 w3 ?. r
- //获取数据( H/ Y( t/ y$ O1 W7 k9 Q2 Y
- array.resize(udpSocket->pendingDatagramSize()); Y+ N, Q* J( t) u& F! J
- udpSocket->readDatagram(array.data(),array.size());
' E# }7 T, J4 A1 {- {8 H - buf = array.data();
# B+ F$ M3 k# n9 P! }7 K! p* j - ui->recvEdit->appendPlainText(buf);
! e, n/ F* o' V9 U( W - }2 i E$ T6 p2 ~* ?3 U/ j$ F
- }
: W5 Z2 C: `3 _* D( A/ F U - /*' x7 m% t6 M+ t8 {# n
- * 发送数据
# P1 P2 V- Y+ ^2 i - */% ]" q+ V# X5 C U+ }
- void Udp::on_pushButton_3_clicked()7 k {3 {0 ~( c6 T$ G6 O
- {9 U# w- j" A- _7 b' j- c+ f
- quint16 port;
0 |" E9 Y) d9 ]; u - QString sendBuff;) c/ i; s: t# }8 b( T5 P
- QHostAddress address;
7 n5 ?5 S% j" E9 u' T5 o4 w% N - address.setAddress(ui->ipEdit->text());//目标机地址5 W, q) B& e& v8 ]
- port = ui->portEdit->text().toInt();//目标机端口号
, w0 `& L; V1 ?1 i9 |0 n) } - sendBuff = ui->sendEdit->text();//发送的数据
' m- B! N5 k( ~/ m - //发送, B/ n9 [( N6 Y) P, \2 w
- udpSocket->writeDatagram(sendBuff.toLocal8Bit().data(),sendBuff.length(),address,port);
% E" ~6 J0 x# V, e4 B. Q2 f W - }
2 c% G0 B7 B7 z f - /*0 e& _9 E+ z6 \1 C
- *关闭. \7 b- w9 H M3 S
- */8 Z+ w+ v% d2 `5 M- [
- void Udp::on_pushButton_2_clicked()
, |7 W5 [# g* z - {
) }- r t1 H, k. y4 K! L e: G { - udpSocket->close();- P# ^- r3 F& F! a& c2 s9 G5 G/ B
- }
复制代码
# v9 k( s0 E2 d7 Z9 E- n/ c: Z
. W5 w( h( U/ n& l4 ]6 P1 l |
|