|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
UDP 协议是开放式,无连接,不可靠的传输层通信协议,但它收发数据的速度相对于 TCP 快很多,常用在传输音视频等数据量非常大的场合。% j7 p7 v! u. B ?
udp 网络编程只需要使用一个类 QUdpSocket。
3 a5 q' a! T0 |' V! n
0 ~) ^* h: ]1 ~$ f
本实验中对 QUdpSocket 的基本使用:7 I }) y9 _) o* S, t( H" Y+ z
1.创建 QUdpSocket 对象。4 {' L( ^' r; {
2.绑定端口号
3 M( Z5 n2 ?. W- A3.数据到来触发 readyRead()信号。
" e% ?1 ^1 [1 e6 g4.读取发送数据。/ m3 W6 {3 @0 {4 M4 X2 f2 `
5.关闭。, g# f8 d1 E# A+ B
具体步骤:
9 [5 N4 t, I$ u9 h _5 L步骤一:组装 ui 界面,和 TCP 章节搭建 UI 界面方法一致。
; F' ]# \# R" L( m k
5 L4 q/ D6 K" j步骤二:编写代码
0 `) j* k% D/ Y( N2 n' v) F0 v; Q: C1.创建 QUdpSocket 对象,使用 bind 函数绑定端口号和套接字,数据报到来后会发出信 号
) }7 N; w+ @& D(),在绑定的槽函数内去读取数据。$ i/ h- T" p8 a, Q/ b) R/ b
2.读取数据,数据到来 hasPendingDatagrams()返回 true,再用 pendingDatagramSize()获取数据报的长度,如果数据没有被读取2 x; c; M% q4 A
完,hasPendingDatagrams()就会返回 true,直至数据都被读取完。
4 G8 t7 J" _7 Q4 D6 t9 J, [2 RreadDatagram(data,size);: ?% H1 A, f5 i5 [2 A S0 M
参数 data 为读取的数据,size 为数据长度。
% g+ h; z$ j, j! J3.发送数据,使用 writeDatagram 函数,
4 r2 |0 v9 m2 Z' Q. ^writeDatagram(const char *data, qint64 len, const QHostAddress &host, quint16 port);3 j7 E7 |3 b' V$ r& I, \
Data:发送的数据。% _1 Q: f) m) n2 i" v0 x1 ?
Len:发送的数据长度。
4 `/ d3 h' G% J% Z8 G' s. eHost:目标 IP 地址。
3 g( G6 Z' n' ?" P, I/ EPort:目标端口号。+ Y0 o, H+ G8 f
4.关闭 socket 套接字。7 ]) X9 ~( g( t. E, P3 _+ d: E. f
代码如下:6 H+ {! D5 O& J# c5 E8 D
- udp.h9 J: Y* N* w! A' w1 r- x
- #include <QMainWindow> k, C' l. j- q9 z! j
- #include <QUdpSocket>
5 c& A3 R+ |. a8 b# q - namespace Ui {# N& R& U$ ?! B- y3 w0 T
- class Udp;
+ I" o: r. U" D& I4 w+ k - }
6 a- O: }/ v0 T$ i; N8 N" N' O - class Udp : public QMainWindow
1 i/ @. |' t$ X& Q- @# E0 F - {
9 p4 X3 r0 |- P, \" W' t - Q_OBJECT! F7 o0 g, {" `4 t" [
- public:& }1 r6 i7 p9 {( k% W# C( h
- explicit Udp(QWidget *parent = 0); ~Udp();
) F' j. b0 d7 v" V T. ~ - QUdpSocket * udpSocket;
: s4 `+ p" N! A* r4 S - private slots:7 p3 q0 ^( X W( P: m& |
- void on_pushButton_clicked();
6 @0 V0 l( i8 }0 e% N - void readyRead_Slot(void);: J0 G9 g/ F) f7 @
- void on_pushButton_3_clicked();0 v. Y! X& ~ ?5 H$ w" A: A
- void on_pushButton_2_clicked();
9 t: a( E3 s( y - private:
% ~1 f, f/ s8 M, l - Ui::Udp *ui; y8 v! h: i8 }
- };
* _3 K3 @( T5 E8 e - udp.cpp:' ]+ ~) R4 ^2 V, X* h, M
- Udp::Udp(QWidget *parent) :6 V8 A" |! ^# Y
- QMainWindow(parent), ui(new Ui::Udp)$ F1 n- P* D* x$ \% d0 c3 Y
- {0 \6 Y# [! N" u5 z5 j
- ui->setupUi(this);
, C: k8 E, Q# F- `% m - udpSocket = new QUdpSocket(this);
, o( J, k, x9 m" O- G5 z/ b - }6 @/ T- b- d4 z1 U+ K1 E/ z2 _
- Udp::~Udp()
6 [, \4 \3 j0 ?/ }: |4 h4 K - {
4 h; L1 \# i! X! m - delete ui;2 ^" g' @% Y4 d+ [
- }% e' Q3 ^& a1 b& }, d( z. S, Z
- /*
/ x+ u: k: Z& J4 @* P5 ~ - * 打开按钮
* l! K8 m6 W7 r* p - */
5 P, f' m7 P: R8 x6 H' H - void Udp::on_pushButton_clicked()) i. I- f6 G' q3 N5 w8 }* c
- {
2 x$ _, N$ M# q/ w( A3 M - //绑定本端口的端口号
. S0 S, j2 y' ?5 o! J - if(udpSocket->bind(ui->cliEdit->text().toUInt()) == true){
4 c5 |9 V! A+ [) t+ R/ a - QMessageBox::information(this,"提示","成功");! S8 I* \, K: \
- }else{3 A: H4 W0 w1 o; g3 W7 m0 F0 a' Z
- QMessageBox::information(this,"提示","失败");
& X K% z7 a! [! v' t! ~& B" @) M - }
, h; y' y. e. L5 C- t - //绑定数据信号和槽函数
0 i$ z& T1 o0 i$ i+ A' y - connect(udpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));- ?0 s5 x) @3 [6 E' {
- }
, X' X7 Y! s$ [/ n7 S - /*5 Q' A$ R0 p- Z4 o* p: M4 u; |
- *读取数据槽函数
3 E6 N+ e, t8 m( M5 [/ J8 k - */
6 F) {3 g1 Z9 `% Z" {# w+ ^% I" B - void Udp::readyRead_Slot()$ [( B y Y! X7 f7 G& i
- {
6 C' k: R& {0 V- ^. h' l$ i3 c) V - QString buf;! K/ @* F* @$ D; d9 S
- QByteArray array;
; B* o1 Y# a8 a: A& P- ` k2 [. f: K - //hasPendingDatagrams()返回 true 时表示至少有一个数据报在等待被读取- e! c2 Y& s, ^+ n3 h) {7 x
- while(udpSocket->hasPendingDatagrams()){
* I% W+ _; b7 M. }) ]6 O+ ^4 y - //获取数据
7 k" @8 Z3 \, y5 Z4 Z/ S4 r - array.resize(udpSocket->pendingDatagramSize());
/ J0 M1 w5 c, o6 L) ^5 {9 ^* a - udpSocket->readDatagram(array.data(),array.size());7 v1 m- O) Q7 a8 x+ Q
- buf = array.data();
0 |5 R* D( L. F, F - ui->recvEdit->appendPlainText(buf);
8 X2 Y+ |9 q, c$ q# M/ O - }
" e# B! `4 c& S0 m: B - }
5 B! [( F% S& y* ?2 `$ E - /*
/ E- ~# ^6 Z/ J; k2 q8 q - * 发送数据
$ E& I% k' E/ @" ? - */
) V. \/ \ u( S& L- D8 F. L: [ ^ - void Udp::on_pushButton_3_clicked()
; M- t/ S! F1 e. I4 E& Q; E" H - {" _( S1 L' h) U7 D) |
- quint16 port;" b5 v" e- R/ |
- QString sendBuff;
5 b! \' m; f) Z$ n/ U% X6 l - QHostAddress address;+ {4 C% N0 D: p
- address.setAddress(ui->ipEdit->text());//目标机地址$ `- |7 b; @! F E
- port = ui->portEdit->text().toInt();//目标机端口号4 r- X4 k$ ^' j. y( l
- sendBuff = ui->sendEdit->text();//发送的数据
& `- U( H/ P. v; }7 ^& r - //发送
5 @+ W0 J- Y- `3 p - udpSocket->writeDatagram(sendBuff.toLocal8Bit().data(),sendBuff.length(),address,port);) t/ e2 @2 {/ B% j: R/ e0 ~1 v+ s
- }5 {1 _; H( y6 Q4 _+ q6 m# e/ l
- /*! I7 c( t5 i5 t- H& a8 c% ~
- *关闭0 {% v6 I7 w, W. i1 K* t
- */" ]+ h8 U, _" b6 b& x ]( j8 s/ q( ^/ I
- void Udp::on_pushButton_2_clicked()% V5 E( q; |5 v; {7 b. o
- {
; F, N7 B j8 s8 m( U$ I - udpSocket->close();
4 X+ K( D8 `, j5 I, x* [, R j7 z& m - }
复制代码
" }; r! t3 t2 r
' P. [, d& a6 J) {% l. F |
|