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

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

[复制链接]

该用户从未签到

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

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
  1. udp.h
    2 g' n5 Y  e7 _2 M) B0 D
  2. #include <QMainWindow>
    - i' B# `5 H6 F* ?6 _: k. @
  3. #include <QUdpSocket>
    3 Y2 u: [1 y; K" U
  4. namespace Ui {
    % T- M* H4 y: V% S) u
  5. class Udp;) ?6 r( T6 k8 V
  6. }: w5 m. R) j) f" r3 r
  7. class Udp : public QMainWindow2 R* Y' ^/ A! a
  8. {
    4 ?: Q" j1 p& D; i; e& Q
  9. Q_OBJECT
    5 N$ ~" F# E* N
  10. public:
    : x- s! t& ?& X) l6 n
  11. explicit Udp(QWidget *parent = 0); ~Udp();- D; K" i" t. d  K# K
  12. QUdpSocket * udpSocket;
    % ]' G" m  e/ @' A+ h( T( ?
  13. private slots:
    ; l; O# i# ^% A+ T, Z) k6 @* v" B
  14. void on_pushButton_clicked();6 V, T3 ?; g1 ^: [& o; @8 _
  15. void readyRead_Slot(void);0 U1 }2 [. e% ^
  16. void on_pushButton_3_clicked();+ p3 g* c! u6 U9 K! O
  17. void on_pushButton_2_clicked();+ P1 L' L7 F" M2 j
  18. private:# \# D" a# H- b6 m
  19. Ui::Udp *ui;, V) q$ I+ B+ v: V; L( i
  20. };/ p% |; @! V" _
  21. udp.cpp:
      t6 Y0 f0 T4 ~3 G1 t+ r
  22. Udp::Udp(QWidget *parent) :1 A+ F" r: f% r8 L$ s# w; c
  23. QMainWindow(parent), ui(new Ui::Udp)* c+ Y7 p8 j3 m- P8 G7 c& c
  24. {+ r$ C1 m0 ]+ u& s% R$ u# j
  25. ui->setupUi(this);) V) X5 \4 w8 C% \; p1 ^' |' Z3 O
  26. udpSocket = new QUdpSocket(this);7 K. d, G! ~% r, O$ `9 n8 O
  27. }" q  d4 k8 @5 m0 n' s
  28. Udp::~Udp()4 _# H6 O6 ?; W1 h
  29. {
    9 W  Z+ |* T1 F5 U" b
  30. delete ui;
    9 `9 _1 E6 J# h7 y
  31. }, _5 s3 H  ~9 p6 \: A
  32. /*1 t" W! V% q/ |  Q$ m# C
  33. * 打开按钮7 i7 s& L/ O" ]
  34. */* O$ ~% \0 R! Z2 f7 w
  35. void Udp::on_pushButton_clicked()
    # L0 p2 Y) n& k
  36. {
    ; |4 E# o* g: I  i+ c- R% G* f
  37. //绑定本端口的端口号
    ; H* ~  K$ |! Y4 ~) c: i
  38. if(udpSocket->bind(ui->cliEdit->text().toUInt()) == true){% q" z2 b5 [4 m- q& B" c' ?
  39. QMessageBox::information(this,"提示","成功");2 A( Y6 u4 _$ Q
  40. }else{/ q7 f0 x9 M4 N1 f) q% G: ~$ J. ~
  41. QMessageBox::information(this,"提示","失败");
    0 R" w% i9 K' c0 {6 W* K
  42. }6 `0 f# K4 g5 e
  43. //绑定数据信号和槽函数6 }( Z/ z) Q6 Z8 s; Z
  44. connect(udpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));9 O2 ?" a1 j. l$ n
  45. }3 X* x& B- g9 U" D4 A/ ?
  46. /** A* A8 u" @4 m1 v! ]) O$ K
  47. *读取数据槽函数
    9 I% r4 n2 `8 B4 d# ~
  48. */
    ! y- D' C6 @* L) I1 ^
  49. void Udp::readyRead_Slot()' J/ ?. S0 F2 _' o# e9 g* _
  50. {3 H) c# R2 K: J& c
  51. QString buf;( X0 t4 k% j: h9 r: o
  52. QByteArray array;9 E2 {& h' b- R. C" J
  53. //hasPendingDatagrams()返回 true 时表示至少有一个数据报在等待被读取9 B) ]5 r, E/ C. C1 c( B
  54. while(udpSocket->hasPendingDatagrams()){4 A( T  T& z8 c! [5 R7 w3 ?. r
  55. //获取数据( H/ Y( t/ y$ O1 W7 k9 Q2 Y
  56. array.resize(udpSocket->pendingDatagramSize());  Y+ N, Q* J( t) u& F! J
  57. udpSocket->readDatagram(array.data(),array.size());
    ' E# }7 T, J4 A1 {- {8 H
  58. buf = array.data();
    # B+ F$ M3 k# n9 P! }7 K! p* j
  59. ui->recvEdit->appendPlainText(buf);
    ! e, n/ F* o' V9 U( W
  60. }2 i  E$ T6 p2 ~* ?3 U/ j$ F
  61. }
    : W5 Z2 C: `3 _* D( A/ F  U
  62. /*' x7 m% t6 M+ t8 {# n
  63. * 发送数据
    # P1 P2 V- Y+ ^2 i
  64. */% ]" q+ V# X5 C  U+ }
  65. void Udp::on_pushButton_3_clicked()7 k  {3 {0 ~( c6 T$ G6 O
  66. {9 U# w- j" A- _7 b' j- c+ f
  67. quint16 port;
    0 |" E9 Y) d9 ]; u
  68. QString sendBuff;) c/ i; s: t# }8 b( T5 P
  69. QHostAddress address;
    7 n5 ?5 S% j" E9 u' T5 o4 w% N
  70. address.setAddress(ui->ipEdit->text());//目标机地址5 W, q) B& e& v8 ]
  71. port = ui->portEdit->text().toInt();//目标机端口号
    , w0 `& L; V1 ?1 i9 |0 n) }
  72. sendBuff = ui->sendEdit->text();//发送的数据
    ' m- B! N5 k( ~/ m
  73. //发送, B/ n9 [( N6 Y) P, \2 w
  74. udpSocket->writeDatagram(sendBuff.toLocal8Bit().data(),sendBuff.length(),address,port);
    % E" ~6 J0 x# V, e4 B. Q2 f  W
  75. }
    2 c% G0 B7 B7 z  f
  76. /*0 e& _9 E+ z6 \1 C
  77. *关闭. \7 b- w9 H  M3 S
  78. */8 Z+ w+ v% d2 `5 M- [
  79. void Udp::on_pushButton_2_clicked()
    , |7 W5 [# g* z
  80. {
    ) }- r  t1 H, k. y4 K! L  e: G  {
  81. udpSocket->close();- P# ^- r3 F& F! a& c2 s9 G5 G/ B
  82. }
复制代码

# v9 k( s0 E2 d7 Z9 E- n/ c: Z
. W5 w( h( U/ n& l4 ]6 P1 l
  • 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-10-9 14:10 , Processed in 0.140625 second(s), 26 queries , Gzip On.

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

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

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