|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
UDP 协议是开放式,无连接,不可靠的传输层通信协议,但它收发数据的速度相对于 TCP 快很多,常用在传输音视频等数据量非常大的场合。
% M2 a: M7 N0 M5 G7 O( g6 h; zudp 网络编程只需要使用一个类 QUdpSocket。9 I# g, K, f5 R+ C& U
9 C9 G5 {1 M% ]# Z本实验中对 QUdpSocket 的基本使用:
Z" Y; m, _) h% m$ U3 g1.创建 QUdpSocket 对象。
6 N3 c2 J+ A/ ?8 o9 ~$ W2.绑定端口号+ U- H/ N2 [: P% ?
3.数据到来触发 readyRead()信号。6 k4 {: @7 p/ G& a& H9 q
4.读取发送数据。0 I/ Y" s5 t* ^+ e2 l7 a. ]* v
5.关闭。
: b l% W! m. Z* v具体步骤:
2 i: `, o1 X9 ^1 `步骤一:组装 ui 界面,和 TCP 章节搭建 UI 界面方法一致。
/ n2 ?: ]. H" w/ O i( M3 P! L
% V4 a/ X/ _3 Y1 W) |0 E5 W8 n4 m步骤二:编写代码
* A2 O# E7 c `; r! v, ~: n" b( N1.创建 QUdpSocket 对象,使用 bind 函数绑定端口号和套接字,数据报到来后会发出信 号
- M# \ n* F3 l" {. P Q6 x(),在绑定的槽函数内去读取数据。
% n1 c! M+ G- T$ z% o2.读取数据,数据到来 hasPendingDatagrams()返回 true,再用 pendingDatagramSize()获取数据报的长度,如果数据没有被读取, W( @6 l, E8 |) q1 F5 f$ X- \; \( ~5 W
完,hasPendingDatagrams()就会返回 true,直至数据都被读取完。
% g7 T& i$ F4 hreadDatagram(data,size);
# s2 u3 e4 b* u v! o% L, p# v参数 data 为读取的数据,size 为数据长度。
6 s/ [; ]7 Z2 C; G( B7 E$ I8 L3.发送数据,使用 writeDatagram 函数,* ~3 x2 j$ M. ~" C) |+ N
writeDatagram(const char *data, qint64 len, const QHostAddress &host, quint16 port);
/ V3 T# X4 k( o$ _Data:发送的数据。9 N/ C& ]; X t- A3 q1 n0 O
Len:发送的数据长度。6 e4 a9 r/ O4 O; J I7 l
Host:目标 IP 地址。1 B& M6 ]7 {# l% w
Port:目标端口号。3 t2 r* Q5 S2 P* s
4.关闭 socket 套接字。1 t5 t: ?: }6 x. E" n0 i9 s
代码如下:; a0 t: |# p6 U' d7 I
- udp.h0 T3 s. D n, W
- #include <QMainWindow>
* u( z: t+ q# P! ^( @7 G - #include <QUdpSocket>
0 A4 q5 x! j9 L$ y8 ^' k - namespace Ui {
. W5 f9 V" o. Y5 ^ - class Udp;
4 y* l( ]& D c+ q/ h: Z - }) a. D y- H2 I+ u( b
- class Udp : public QMainWindow6 ~+ y0 i: m- q& E+ E' k- R3 c
- {
& B) X$ p5 _$ C - Q_OBJECT
1 x; {5 e2 t) o. R$ w - public:
; F( D3 l( Y8 Y" c2 x6 n1 R - explicit Udp(QWidget *parent = 0); ~Udp();
2 ^2 m; F# N+ m, ~/ F - QUdpSocket * udpSocket;& [! l% }( J9 D7 ?( G1 ~9 u$ H0 ^
- private slots:: Q( b7 p7 h/ p" ^& R
- void on_pushButton_clicked();( e1 F8 ?' F% O
- void readyRead_Slot(void);% C! a# l8 M/ P; ~/ \
- void on_pushButton_3_clicked();
) E! r. u# z6 T( O" S+ H: p - void on_pushButton_2_clicked();
- A0 h4 B" h" Z. b$ u6 P - private:
, C. C' D" h; f - Ui::Udp *ui;( i/ M5 n# b7 d; Z9 u2 x
- };
2 p9 h, H4 X& ], V0 N% p& ] - udp.cpp:; g( X4 G4 p+ d' _
- Udp::Udp(QWidget *parent) :4 U8 l, k1 i' S
- QMainWindow(parent), ui(new Ui::Udp)
. O9 y0 c5 c7 k9 T - {1 a3 D! G, p2 J* {# r1 B& U5 o9 o
- ui->setupUi(this);8 s7 J% R# ^7 p: I7 |
- udpSocket = new QUdpSocket(this);
( d1 V( p) l, y2 }5 o - }8 N9 f9 [ H' X
- Udp::~Udp()
3 v1 b2 _' }: ] - {/ S& u; v3 E. P) @+ E b0 `( p
- delete ui;" j! m5 C/ b' Q$ M
- }
: c$ y' l6 C) u( J4 q7 ] - /*
7 A v3 ~0 c e/ c - * 打开按钮
Z$ Q4 U6 ?/ j" M+ f6 Q" E - */3 Y# W: p/ G' u" R
- void Udp::on_pushButton_clicked() p6 o, y) X' i/ Z; }8 |" F
- {( C, R; _" B) f4 ]. U/ h$ ]- K, c
- //绑定本端口的端口号
5 b: Q( [4 F. a2 Y t7 _% s - if(udpSocket->bind(ui->cliEdit->text().toUInt()) == true){; O+ _8 Z- p8 C. H# u: u
- QMessageBox::information(this,"提示","成功");* Z9 o3 ~1 v: M V; P
- }else{
+ B8 p2 I! N7 o& L; K: h - QMessageBox::information(this,"提示","失败");
- R9 R' }- v* I - }
0 T7 g2 X8 |4 ?8 E4 w - //绑定数据信号和槽函数
& m) f( x3 t# K$ E - connect(udpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));
d* Q) q) b- `0 d( K - }0 m& O6 x! l! j' V& x+ q
- /*
# H2 q, C: U) R, N - *读取数据槽函数2 k1 r8 Y. h0 ^% V( G( W
- */
4 C i: U6 X2 `& p5 k6 e - void Udp::readyRead_Slot(): D" i" N- A6 r+ n# }
- {% x# G& u4 r2 z( h! k9 w1 b& T& H
- QString buf;
# V# d4 J1 X6 P0 f8 C) V; b - QByteArray array;
g0 V+ v3 o9 { l& i( ^: } - //hasPendingDatagrams()返回 true 时表示至少有一个数据报在等待被读取
1 N1 e1 M, d8 }9 _" v - while(udpSocket->hasPendingDatagrams()){; ^1 M$ k1 K- e3 ^- f* b" N3 ~. A
- //获取数据
! E7 N; R2 h: o+ L - array.resize(udpSocket->pendingDatagramSize());
( u+ D7 E- H1 o4 r4 x1 e% G; S - udpSocket->readDatagram(array.data(),array.size());
1 k N, Z6 S5 A# N8 V) n" c - buf = array.data();4 L$ q: \ r- b% J
- ui->recvEdit->appendPlainText(buf);
# q! n$ C2 ^5 V& b - }2 v/ \6 B: h" }
- }/ q, _* @. {8 ~& U8 u
- /*
" L. J5 f; \9 G( c - * 发送数据
; K" |% P; Z6 `7 R - */
3 o$ Z* ~" h* `4 B3 Q/ _" |, t5 { - void Udp::on_pushButton_3_clicked(): E$ e! B! o$ J0 \
- {3 g9 o0 ], ~- F' D
- quint16 port;
G! W7 C5 g3 f0 m( N/ I8 d/ Q |* e - QString sendBuff;/ A; t: l6 L' T- `' K; N
- QHostAddress address;
" |! |$ @3 ?: ^+ h; q. g - address.setAddress(ui->ipEdit->text());//目标机地址) t j+ s- K. _3 p: b: ^
- port = ui->portEdit->text().toInt();//目标机端口号2 i8 ~2 S$ [" z5 ?8 O
- sendBuff = ui->sendEdit->text();//发送的数据5 W) s: Q# a5 A0 H) I
- //发送
7 C5 k6 M! D: N0 G( I - udpSocket->writeDatagram(sendBuff.toLocal8Bit().data(),sendBuff.length(),address,port);% v* r0 ]7 u, h
- }
* U7 W6 H, m, D/ }. e9 n" G/ p - /*% V8 U& B! v7 \, N/ C7 c
- *关闭" {# q# ~( e+ W6 H
- */
, C O$ V [# P& L1 h- J/ b+ u - void Udp::on_pushButton_2_clicked()
0 } K1 G0 k: U, W- f3 Q - {
{% T3 Y7 m! C2 l8 A, W9 w2 @% N( G - udpSocket->close();# y' A. @$ _ ]
- }
复制代码
" z/ n# a/ s5 ?0 B- i
6 Z& L6 S, }6 Y" x* x# T
|
|