找回密码
 注册
关于网站域名变更的通知
查看: 617|回复: 1
打印 上一主题 下一主题

迅为4412开发板Qt网络编程-UDP实现服务器和客户端

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2021-5-13 10:49 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
UDP 协议是开放式,无连接,不可靠的传输层通信协议,但它收发数据的速度相对于 TCP 快很多,常用在传输音视频等数据量非常大的场合。9 N$ }+ O7 H4 ?7 q; d' q
udp 网络编程只需要使用一个类 QUdpSocket。- ^* |. E1 R0 ?6 @
5 p/ L! q9 X& s2 u$ Q8 W3 e4 {! k" K
本实验中对 QUdpSocket 的基本使用:
  }) B! T& u: Z$ A9 l+ {1.创建 QUdpSocket 对象。$ u$ i( L" p4 w5 ?* t
2.绑定端口号$ g4 G* m1 o9 U+ \, v  f3 o
3.数据到来触发 readyRead()信号。
& J$ W- K1 k& x/ }  T4.读取发送数据。
4 `; U2 @$ V5 n5 d1 O8 `5.关闭。
" B/ T1 I8 a; U5 j/ G具体步骤:
$ x- x# {$ h* q+ p步骤一:组装 ui 界面,和 TCP 章节搭建 UI 界面方法一致。
; `8 A+ a0 N/ m& U# t8 I8 t+ Q ( |; x3 S3 ]+ k/ x- h
步骤二:编写代码
  P- J! o3 }& l* x$ S6 Y+ |1.创建 QUdpSocket 对象,使用 bind 函数绑定端口号和套接字,数据报到来后会发出信 号
0 h5 n% v. @& j! N/ X% R( |(),在绑定的槽函数内去读取数据。4 c; {. P  T3 D* m' d! c
2.读取数据,数据到来 hasPendingDatagrams()返回 true,再用 pendingDatagramSize()获取数据报的长度,如果数据没有被读取# z0 E/ ?+ D* t2 }  P2 {" b
完,hasPendingDatagrams()就会返回 true,直至数据都被读取完。) Y1 r, c5 V% c2 F) C& J- v
readDatagram(data,size);* V7 _  }, q5 F# @1 a9 b- ?$ b
参数 data 为读取的数据,size 为数据长度。' R2 j( f0 x7 ^) b& y. P5 \
3.发送数据,使用 writeDatagram 函数,8 b- k' s. s7 B1 h' T$ N) ]
writeDatagram(const char *data, qint64 len, const QHostAddress &host, quint16 port);5 U% M( ]& N$ U, U
Data:发送的数据。* w2 \0 ]4 k; L$ r
Len:发送的数据长度。% \4 _5 D0 O/ O: T& G
Host:目标 IP 地址。  ^8 k2 j  Q+ ^8 Z
Port:目标端口号。
" i$ \5 h( I# A% c- d- _1 E" k4.关闭 socket 套接字。
; k* O' b: {# z& W代码如下:
9 r4 H& R8 g) u; M& t  o' a
  1. udp.h
      v/ w1 D1 W  R( s7 K7 W- h9 ]
  2. #include <QMainWindow>* y! v9 i2 P( h5 U; b8 e
  3. #include <QUdpSocket>
    , S/ M* t1 K. b+ V
  4. namespace Ui {5 i- |9 n1 j# O9 q
  5. class Udp;
    " W% r8 M. K# J7 S
  6. }
    $ B# N' f( L0 e& _4 j
  7. class Udp : public QMainWindow# \& R% J1 i1 _+ P
  8. {; d$ y7 ~' N  K3 F0 l8 Q# d0 v9 m2 T
  9. Q_OBJECT' L. y2 {' W; {" R$ K+ C
  10. public:
    0 Q9 ?! a, A! J% c
  11. explicit Udp(QWidget *parent = 0); ~Udp();2 f5 F" n6 C% e  I+ F
  12. QUdpSocket * udpSocket;: Z# g6 j8 ?2 m# m
  13. private slots:' n8 O! K+ k( f; {; F
  14. void on_pushButton_clicked();
    5 ]6 T. o) {2 {# y+ p7 |3 r( t
  15. void readyRead_Slot(void);# X" c% s' ~" G- b& }! l, {
  16. void on_pushButton_3_clicked();
    1 e' o) a8 N; [- j
  17. void on_pushButton_2_clicked();0 `/ l7 z0 b/ U$ `( t
  18. private:
    , w0 w# }$ U! G1 X7 R. m
  19. Ui::Udp *ui;
    1 p, p. R9 \& R1 D+ H
  20. };4 [% t: W) d7 \3 z+ P* l$ V5 x
  21. udp.cpp:% @4 j. ~! d6 L$ v
  22. Udp::Udp(QWidget *parent) :
    6 U0 o5 n9 `7 Z
  23. QMainWindow(parent), ui(new Ui::Udp)3 a7 P, V/ b, P6 J* K1 k
  24. {6 x( x0 ^9 B) ~4 s8 _4 d/ v8 |
  25. ui->setupUi(this);
    ! L+ j8 I, C6 n
  26. udpSocket = new QUdpSocket(this);
    4 E9 c9 d6 C& l' s. X, ?' q
  27. }
    2 r% C( X. n2 m7 j9 v. V
  28. Udp::~Udp()8 ^0 \: H2 q! M3 s7 X2 R* p
  29. {: ~1 Q! A& n! o8 |; X, l7 Y
  30. delete ui;
    % S1 i6 r2 K% a4 D( M
  31. }% p! `  o6 V$ A
  32. /*" A: m1 A" [( R# F5 X! e- M
  33. * 打开按钮0 S* D" C" e1 X5 F4 i$ Z' {
  34. */) H& j+ `6 v7 }+ A& G- A3 b- a
  35. void Udp::on_pushButton_clicked()' L/ P$ f/ T! j% \
  36. {
    , {8 j2 y: A6 q2 Y
  37. //绑定本端口的端口号
    : n; ~& ]* |/ g
  38. if(udpSocket->bind(ui->cliEdit->text().toUInt()) == true){
    6 ^# h. f6 [: F3 S2 h% }9 A" W
  39. QMessageBox::information(this,"提示","成功");2 i3 f, G7 x1 C! ~4 r% ~
  40. }else{7 q+ @8 V# }( n5 q3 B) \7 E
  41. QMessageBox::information(this,"提示","失败");$ @8 U- ~7 m& E4 C# V) Z, o
  42. }2 q" Z# H0 s/ K# ~5 H4 H! H/ }
  43. //绑定数据信号和槽函数
    0 O7 J/ ~  G) q" v1 P: s8 N
  44. connect(udpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));' S# |9 n2 q" ^- A- L
  45. }
    6 A% k7 L0 @: ^& t! a) x
  46. /*
    6 Z% X# @# P0 l, m
  47. *读取数据槽函数
    1 }  N& v' U' y9 q  k
  48. */- c( K( H( D& N- f0 O! n
  49. void Udp::readyRead_Slot()
    ; T! C3 [5 J7 t# j4 W
  50. {& |- Q$ E6 z8 l
  51. QString buf;
      o) g+ l0 n- u4 m6 O9 l) A/ e
  52. QByteArray array;# k+ s. K: L2 P) |
  53. //hasPendingDatagrams()返回 true 时表示至少有一个数据报在等待被读取
    2 R6 ]  G! i4 S
  54. while(udpSocket->hasPendingDatagrams()){
    * `0 P7 |2 [$ U: t0 h" T1 R" L( v
  55. //获取数据+ E6 n$ V* \5 _% f7 J
  56. array.resize(udpSocket->pendingDatagramSize());8 n% q. x" h0 k9 H6 D+ Z' _
  57. udpSocket->readDatagram(array.data(),array.size());
    : @/ m$ ^' \2 P1 `/ x) Q! j
  58. buf = array.data();7 J1 |- W/ F9 s6 X
  59. ui->recvEdit->appendPlainText(buf);
    9 e1 y3 C* l  Z; b& E( S1 M
  60. }! S5 y/ w0 \8 H2 u" P, W& {
  61. }7 N& z5 M: H3 Y1 Q& t  T# O
  62. /*% t' B2 V) P1 Q0 @" o6 ?
  63. * 发送数据1 M! Q( K& W9 V9 t1 g9 T
  64. */$ e3 Q  k3 S5 D6 M( m% S5 s4 a) ?
  65. void Udp::on_pushButton_3_clicked()
    0 O, v! B! D* v8 L6 Q
  66. {9 T0 e  T  ~/ \! e. q  c0 j
  67. quint16 port;
    + c2 g$ q" t4 D" w  M; o/ ]) L# w
  68. QString sendBuff;
    $ j  U* }! l1 `1 Q; r; g
  69. QHostAddress address;; d$ s$ F& l1 Y8 L  N
  70. address.setAddress(ui->ipEdit->text());//目标机地址1 f3 @. \) N& Q4 i
  71. port = ui->portEdit->text().toInt();//目标机端口号3 @' I. @7 k2 c2 I+ E2 u, J$ G- V
  72. sendBuff = ui->sendEdit->text();//发送的数据
    5 p5 H  M0 s  ^% {" Y* f0 P
  73. //发送1 t1 f$ y5 U% s5 ~- f
  74. udpSocket->writeDatagram(sendBuff.toLocal8Bit().data(),sendBuff.length(),address,port);
    5 l- f: n+ q! n
  75. }
    2 u- y1 ^  i4 i
  76. /*; l3 Q! L3 a0 W4 [6 b, y
  77. *关闭0 H- ~* H# N+ T7 \: N% e1 M
  78. */: {9 r+ {! h7 o5 P7 f: n6 D
  79. void Udp::on_pushButton_2_clicked()2 I& `3 o+ {# C) F7 T/ V  D
  80. {8 |5 g, L# x7 F" H0 `# ^0 U" _
  81. udpSocket->close();
      u$ L& z0 L5 ?
  82. }
复制代码
% x! `3 z2 w9 W+ b0 C

8 W; r* W$ n5 Q/ P# X4 J% K
  • TA的每日心情
    慵懒
    2020-6-13 15:46
  • 签到天数: 1 天

    [LV.1]初来乍到

    2#
    发表于 2021-5-14 13:12 | 只看该作者
    4412开发板Qt网络编程-UDP实现服务器和客户端
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-11-24 09:02 , Processed in 0.156250 second(s), 27 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表