百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

正点原子I.MX6U嵌入式Qt开发指南:第十一章《网络编程 2》

toyiye 2024-08-17 00:19 7 浏览 0 评论

今日头条/西瓜视频/抖音短视频 同名:正点原子

原子哥今日头条/西瓜视频/抖音短视频账号:正点原子-原子哥

感谢各位的关注和支持,你们的关注和支持是正点原子无限前进的动力。

第十一章《网络编程》

由于本章内容较多,所以第十一章《网络编程》将会分为几个部分进行内容的发布,更多文章内容请持续关注今日头条正点原子官方账号。

11.2.3 TCP客户端应用实例

本例目的:了解TCP客户的使用。

例09_tcpclient,TCP客户端(难度:一般)。项目路径为Qt/2/09_ tcpclient。本例大体流程:首先获取本地IP地址。创建一个tcpSocket套接字,然后用tcpSocket套接字使用connectToHost函数连接服务端的主机IP地址和端口,即可相互通信。

项目文件08_tcpserver.pro文件第一行添加的代码部分如下。

09_tcpclient.pro编程后的代码

1   QT       += core gui network

2 

3   greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

4 

5   CONFIG += c++11

6 

7   # The following define makes your compiler emit warnings if you use

8   # any Qt feature that has been marked deprecated (the exact warnings

9   # depend on your compiler). Please consult the documentation of the

10  # deprecated API in order to know how to port your code away from it.

11  DEFINES += QT_DEPRECATED_WARNINGS

12

13  # You can also make your code fail to compile if it uses deprecated APIs.

14  # In order to do so, uncomment the following line.

15  # You can also select to disable deprecated APIs only up to a certain version of Qt.

16  #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

17

18  SOURCES += \

19      main.cpp \

20      mainwindow.cpp

21

22  HEADERS += \

23      mainwindow.h

24

25  # Default rules for deployment.

26  qnx: target.path = /tmp/${TARGET}/bin

27  else: unix:!android: target.path = /opt/${TARGET}/bin

28  !isEmpty(target.path): INSTALLS += target

在头文件“mainwindow.h”具体代码如下。

mainwindow.h编程后的代码

    /******************************************************************

    Copyright ? Deng Zhimao Co., Ltd. 1990-2021. All rights reserved.

    * @projectName   09_tcpclient

    * @brief         mainwindow.h

    * @author        Deng Zhimao

    * @email         1252699831@qq.com

    * @net            www.openedv.com

    * @date           2021-04-13

    *******************************************************************/

1   #ifndef MAINWINDOW_H

2   #define MAINWINDOW_H

3 

4   #include <QMainWindow>

5   #include <QTcpServer>

6   #include <QTcpSocket>

7   #include <QVBoxLayout>

8   #include <QHBoxLayout>

9   #include <QPushButton>

10  #include <QTextBrowser>

11  #include <QLabel>

12  #include <QComboBox>

13  #include <QSpinBox>

14  #include <QHostInfo>

15  #include <QLineEdit>

16  #include <QNetworkInterface>

17  #include <QDebug>

18

19  class MainWindow : public QMainWindow

20  {

21      Q_OBJECT

22

23  public:

24      MainWindow(QWidget *parent = nullptr);

25      ~MainWindow();

26

27  private:

28      /* 通信套接字 */

29      QTcpSocket *tcpSocket;

30

31      /* 按钮 */

32      QPushButton *pushButton[4];

33

34      /* 标签文本 */

35      QLabel *label[2];

36

37      /* 水平容器 */

38      QWidget *hWidget[3];

39

40      /* 水平布局 */

41      QHBoxLayout *hBoxLayout[3];

42

43      /* 垂直容器 */

44      QWidget *vWidget;

45

46      /* 垂直布局 */

47      QVBoxLayout *vBoxLayout;

48

49      /* 文本浏览框 */

50      QTextBrowser *textBrowser;

51

52      /* 用于显示本地ip */

53      QComboBox *comboBox;

54

55      /* 用于选择端口 */

56      QSpinBox  *spinBox;

57

58      /* 文本输入框 */

59      QLineEdit *lineEdit;

60

61      /* 存储本地的ip列表地址 */

62      QList<QHostAddress> IPlist;

63

64      /* 获取本地的所有ip */

65      void getLocalHostIP();

66

67  private slots:

68      /* 连接 */

69      void toConnect();

70

71      /* 断开连接 */

72      void toDisConnect();

73

74      /* 已连接 */

75      void connected();

76

77      /* 已断开连接 */

78      void disconnected();

79

80      /* 清除文本框时的内容 */

81      void clearTextBrowser();

82

83      /* 接收到消息 */

84      void receiveMessages();

85

86      /* 发送消息 */

87      void sendMessages();

88

89      /* 连接状态改变槽函数 */

90      void socketStateChange(QAbstractSocket::SocketState);

91  };

92  #endif // MAINWINDOW_H

头文件里主要是声明界面用的元素,及一些槽函数。重点是声明tcpSocket。

在源文件“mainwindow.cpp”具体代码如下。

mainwindow.cpp编程后的代码

    /******************************************************************

    Copyright ? Deng Zhimao Co., Ltd. 1990-2021. All rights reserved.

    * @projectName   09_tcpclient

    * @brief         mainwindow.cpp

    * @author        Deng Zhimao

    * @email         1252699831@qq.com

    * @net            www.openedv.com

    * @date           2021-04-13

    *******************************************************************/

1   #include "mainwindow.h"

2  

3   MainWindow::MainWindow(QWidget *parent)

4       : QMainWindow(parent)

5   {

6       /* 设置主窗体的位置与大小 */

7       this->setGeometry(0, 0, 800, 480);

8  

9       /* tcp套接字 */

10      tcpSocket = new QTcpSocket(this);

11 

12      /* 开始监听按钮 */

13      pushButton[0] = new QPushButton();

14      /* 停止监听按钮 */

15      pushButton[1] = new QPushButton();

16      /* 清空聊天文本按钮 */

17      pushButton[2] = new QPushButton();

18      /* 发送消息按钮 */

19      pushButton[3] = new QPushButton();

20 

21      /* 水平布局一 */

22      hBoxLayout[0] = new QHBoxLayout();

23      /* 水平布局二 */

24      hBoxLayout[1] = new QHBoxLayout();

25      /* 水平布局三 */

26      hBoxLayout[2] = new QHBoxLayout();

27      /* 水平布局四 */

28      hBoxLayout[3] = new QHBoxLayout();

29 

30      /* 水平容器一 */

31      hWidget[0] =  new QWidget();

32      /* 水平容器二 */

33      hWidget[1] =  new QWidget();

34      /* 水平容器三 */

35      hWidget[2] =  new QWidget();

36 

37 

38      vWidget = new QWidget();

39      vBoxLayout = new QVBoxLayout();

40 

41      /* 标签实例化 */

42      label[0] = new QLabel();

43      label[1] = new QLabel();

44 

45      lineEdit = new QLineEdit();

46      comboBox = new QComboBox();

47      spinBox = new QSpinBox();

48      textBrowser = new QTextBrowser();

49 

50      label[0]->setText("服务器地址:");

51      label[1]->setText("服务器端口:");

52 

53      /* 设置标签根据文本文字大小自适应大小  */

54      label[0]->setSizePolicy(QSizePolicy::Fixed,

55                              QSizePolicy::Fixed);

56      label[1]->setSizePolicy(QSizePolicy::Fixed,

57                              QSizePolicy::Fixed);

58 

59      /* 设置端口号的范围,注意不要与主机的已使用的端口号冲突 */

60      spinBox->setRange(10000, 99999);

61 

62      pushButton[0]->setText("连接服务器");

63      pushButton[1]->setText("断开连接");

64      pushButton[2]->setText("清空文本");

65      pushButton[3]->setText("发送消息");

66 

67      /* 设置停止监听状态不可用 */

68      pushButton[1]->setEnabled(false);

69 

70      /* 设置输入框默认的文本 */

71      lineEdit->setText("广州星翼电子科技有限公司");

72 

73      /* 水平布局一添加内容 */

74      hBoxLayout[0]->addWidget(pushButton[0]);

75      hBoxLayout[0]->addWidget(pushButton[1]);

76      hBoxLayout[0]->addWidget(pushButton[2]);

77 

78      /* 设置水平容器的布局为水平布局一 */

79      hWidget[0]->setLayout(hBoxLayout[0]);

80 

81      hBoxLayout[1]->addWidget(label[0]);

82      hBoxLayout[1]->addWidget(comboBox);

83      hBoxLayout[1]->addWidget(label[1]);

84      hBoxLayout[1]->addWidget(spinBox);

85 

86      /* 设置水平容器的布局为水平布局二 */

87      hWidget[1]->setLayout(hBoxLayout[1]);

88 

89      /* 水平布局三添加内容 */

90      hBoxLayout[2]->addWidget(lineEdit);

91      hBoxLayout[2]->addWidget(pushButton[3]);

92 

93      /* 设置水平容器三的布局为水平布局一 */

94      hWidget[2]->setLayout(hBoxLayout[2]);

95 

96      /* 垂直布局添加内容 */

97      vBoxLayout->addWidget(textBrowser);

98      vBoxLayout->addWidget(hWidget[1]);

99      vBoxLayout->addWidget(hWidget[0]);

100     vBoxLayout->addWidget(hWidget[2]);

101

102     /* 设置垂直容器的布局为垂直布局 */

103     vWidget->setLayout(vBoxLayout);

104

105     /* 居中显示 */

106     setCentralWidget(vWidget);

107

108     /* 获取本地ip */

109     getLocalHostIP();

110

111     /* 信号槽连接 */

112     connect(pushButton[0], SIGNAL(clicked()),

113             this, SLOT(toConnect()));

114     connect(pushButton[1], SIGNAL(clicked()),

115             this, SLOT(toDisConnect()));

116     connect(pushButton[2], SIGNAL(clicked()),

117             this, SLOT(clearTextBrowser()));

118     connect(pushButton[3], SIGNAL(clicked()),

119             this, SLOT(sendMessages()));

120     connect(tcpSocket, SIGNAL(connected()),

121             this, SLOT(connected()));

122     connect(tcpSocket, SIGNAL(disconnected()),

123             this, SLOT(disconnected()));

124     connect(tcpSocket, SIGNAL(readyRead()),

125             this, SLOT(receiveMessages()));

126     connect(tcpSocket,

127             SIGNAL(stateChanged(QAbstractSocket::SocketState)),

128             this,

129             SLOT(socketStateChange(QAbstractSocket::SocketState)));

130 }

131

132 MainWindow::~MainWindow()

133 {

134 }

135

136 void MainWindow::toConnect()

137 {

138     /* 如果连接状态还没有连接 */

139     if (tcpSocket->state() != tcpSocket->ConnectedState) {

140         /* 指定IP地址和端口连接 */

141         tcpSocket->connectToHost(IPlist[comboBox->currentIndex()],

142                 spinBox->value());

143     }

144 }

145

146 void MainWindow::toDisConnect()

147 {

148     /* 断开连接 */

149     tcpSocket->disconnectFromHost();

150

151     /* 关闭socket*/

152     tcpSocket->close();

153 }

154

155 void MainWindow::connected()

156 {

157     /* 显示已经连接 */

158     textBrowser->append("已经连上服务端");

159

160     /* 设置按钮与下拉列表框的状态 */

161     pushButton[0]->setEnabled(false);

162     pushButton[1]->setEnabled(true);

163     comboBox->setEnabled(false);

164     spinBox->setEnabled(false);

165 }

166

167 void MainWindow::disconnected()

168 {

169     /* 显示已经断开连接 */

170     textBrowser->append("已经断开服务端");

171

172     /* 设置按钮与下拉列表框的状态  */

173     pushButton[1]->setEnabled(false);

174     pushButton[0]->setEnabled(true);

175     comboBox->setEnabled(true);

176     spinBox->setEnabled(true);

177 }

178

179 /* 获取本地IP */

180 void MainWindow::getLocalHostIP()

181 {

182     // /* 获取主机的名称 */

183     // QString hostName = QHostInfo::localHostName();

184

185     // /* 主机的信息 */

186     // QHostInfo hostInfo = QHostInfo::fromName(hostName);

187

188     // /* ip列表,addresses返回ip地址列表,注意主机应能从路由器获取到

189     // * IP,否则可能返回空的列表(ubuntu用此方法只能获取到环回IP) */

190     // IPlist = hostInfo.addresses();

191     // qDebug()<<IPlist<<endl;

192

193     // /* 遍历IPlist */

194     // foreach (QHostAddress ip, IPlist) {

195     //      if (ip.protocol() == QAbstractSocket::IPv4Protocol)

196     //          comboBox->addItem(ip.toString());

197     //    }

198

199     /* 获取所有的网络接口,

200      * QNetworkInterface类提供主机的IP地址和网络接口的列表 */

201     QList<QNetworkInterface> list

202             = QNetworkInterface::allInterfaces();

203

204     /* 遍历list */

205     foreach (QNetworkInterface interface, list) {

206

207         /* QNetworkAddressEntry类存储IP地址子网掩码和广播地址 */

208         QList<QNetworkAddressEntry> entryList

209                 = interface.addressEntries();

210

211         /* 遍历entryList */

212         foreach (QNetworkAddressEntry entry, entryList) {

213             /* 过滤IPv6地址,只留下IPv4 */

214             if (entry.ip().protocol() ==

215                     QAbstractSocket::IPv4Protocol) {

216                 comboBox->addItem(entry.ip().toString());

217                 /* 添加到IP列表中 */

218                 IPlist<<entry.ip();

219             }

220         }

221     }

222 }

223

224 /* 清除文本浏览框里的内容 */

225 void MainWindow::clearTextBrowser()

226 {

227     /* 清除文本浏览器的内容 */

228     textBrowser->clear();

229 }

230

231 /* 客户端接收消息 */

232 void MainWindow::receiveMessages()

233 {

234     /* 读取接收到的消息 */

235     QString messages = tcpSocket->readAll();

236     textBrowser->append("服务端:" + messages);

237 }

238

239 /* 客户端发送消息 */

240 void MainWindow::sendMessages()

241 {

242     if(NULL == tcpSocket)

243         return;

244

245     if(tcpSocket->state() == tcpSocket->ConnectedState) {

246         /* 客户端显示发送的消息 */

247         textBrowser->append("客户端:" + lineEdit->text());

248

249         /* 发送消息 */

250         tcpSocket->write(lineEdit->text().toUtf8().data());

251     }

252 }

253

254 /* 客户端状态改变 */

255 void MainWindow::socketStateChange(QAbstractSocket::SocketState state)

256 {

257     switch (state) {

258     case QAbstractSocket::UnconnectedState:

259         textBrowser->append("scoket状态:UnconnectedState");

260         break;

261     case QAbstractSocket::ConnectedState:

262         textBrowser->append("scoket状态:ConnectedState");

263         break;

264     case QAbstractSocket::ConnectingState:

265         textBrowser->append("scoket状态:ConnectingState");

266         break;

267     case QAbstractSocket::HostLookupState:

268         textBrowser->append("scoket状态:HostLookupState");

269         break;

270     case QAbstractSocket::ClosingState:

271         textBrowser->append("scoket状态:ClosingState");

272         break;

273     case QAbstractSocket::ListeningState:

274         textBrowser->append("scoket状态:ListeningState");

275         break;

276     case QAbstractSocket::BoundState:

277         textBrowser->append("scoket状态:BoundState");

278         break;

279     default:

280         break;

281     }

282 }

上面的代码主要是客户端开使用connectToHost通过IP地址和端口与服务端连接,如果连接成功,就会发射connected ()信号,同时也连接到接收消息的信号与槽函数。点击发送消息按钮就可以使用tcpSocket发送消息。注意发送消息和接收消息都是通过tcpSocket的read()和write()进行。

11.2.4程序运行效果

开启服务端后,需要选择本地监听的IP地址和监听的端口(特别需要注意,不要选择监听的端口与本地主机的已经使用的端口,所以编者把端口号设置的特别大,查看本地已经使用的端口号可以使用netstat指令。)

启动客户端后,选择需要连接的服务器IP地址和服务器监听的端口。点击连接后就可以相互发送消息了。

注意服务端和客户端都本例都是选择了本地环回IP 127.0.0.1测试。也可以选择本地的其他IP地址进行测试。

TCP服务端:

TCP客户端:

未完待续....

相关推荐

# Python 3 # Python 3字典Dictionary(1)

Python3字典字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中,格式如...

Python第八课:数据类型中的字典及其函数与方法

Python3字典字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值...

Python中字典详解(python 中字典)

字典是Python中使用键进行索引的重要数据结构。它们是无序的项序列(键值对),这意味着顺序不被保留。键是不可变的。与列表一样,字典的值可以保存异构数据,即整数、浮点、字符串、NaN、布尔值、列表、数...

Python3.9又更新了:dict内置新功能,正式版十月见面

机器之心报道参与:一鸣、JaminPython3.8的热乎劲还没过去,Python就又双叒叕要更新了。近日,3.9版本的第四个alpha版已经开源。从文档中,我们可以看到官方透露的对dic...

Python3 基本数据类型详解(python三种基本数据类型)

文章来源:加米谷大数据Python中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。在Python中,变量就是变量,它没有类型,我们所说的"类型"是变...

一文掌握Python的字典(python字典用法大全)

字典是Python中最强大、最灵活的内置数据结构之一。它们允许存储键值对,从而实现高效的数据检索、操作和组织。本文深入探讨了字典,涵盖了它们的创建、操作和高级用法,以帮助中级Python开发...

超级完整|Python字典详解(python字典的方法或操作)

一、字典概述01字典的格式Python字典是一种可变容器模型,且可存储任意类型对象,如字符串、数字、元组等其他容器模型。字典的每个键值key=>value对用冒号:分割,每个对之间用逗号,...

Python3.9版本新特性:字典合并操作的详细解读

处于测试阶段的Python3.9版本中有一个新特性:我们在使用Python字典时,将能够编写出更可读、更紧凑的代码啦!Python版本你现在使用哪种版本的Python?3.7分?3.5分?还是2.7...

python 自学,字典3(一些例子)(python字典有哪些基本操作)

例子11;如何批量复制字典里的内容2;如何批量修改字典的内容3;如何批量修改字典里某些指定的内容...

Python3.9中的字典合并和更新,几乎影响了所有Python程序员

全文共2837字,预计学习时长9分钟Python3.9正在积极开发,并计划于今年10月发布。2月26日,开发团队发布了alpha4版本。该版本引入了新的合并(|)和更新(|=)运算符,这个新特性几乎...

Python3大字典:《Python3自学速查手册.pdf》限时下载中

最近有人会想了,2022了,想学Python晚不晚,学习python有前途吗?IT行业行业薪资高,发展前景好,是很多求职群里严重的香饽饽,而要进入这个高薪行业,也不是那么轻而易举的,拿信工专业的大学生...

python学习——字典(python字典基本操作)

字典Python的字典数据类型是基于hash散列算法实现的,采用键值对(key:value)的形式,根据key的值计算value的地址,具有非常快的查取和插入速度。但它是无序的,包含的元素个数不限,值...

324页清华教授撰写【Python 3 菜鸟查询手册】火了,小白入门字典

如何入门学习python...

Python3.9中的字典合并和更新,了解一下

全文共2837字,预计学习时长9分钟Python3.9正在积极开发,并计划于今年10月发布。2月26日,开发团队发布了alpha4版本。该版本引入了新的合并(|)和更新(|=)运算符,这个新特性几乎...

python3基础之字典(python中字典的基本操作)

字典和列表一样,也是python内置的一种数据结构。字典的结构如下图:列表用中括号[]把元素包起来,而字典是用大括号{}把元素包起来,只不过字典的每一个元素都包含键和值两部分。键和值是一一对应的...

取消回复欢迎 发表评论:

请填写验证码