QT编程系列10--客户端的网络编程
2014-08-14 20:07
337 查看
客户端的网络编程
上一篇文章,我们实现了服务器端程序的编写,首先创建一个服务器对象,然后使其处于监听的状态,当有新连接过来时,进行与新连接的连接工作。连接使用的是套接字socket类实现的对象,通过该类的write方法,定时1S发送数据到连接上的客户端。我们从中可以看出,这次网络通信首先是有客户发起的,那么客户端是怎么发送这个连接的了,以及连接成功后怎么接收或发送数据的?这就是本篇要讲解的内容。
首先我们要先设计好客户端的界面布局。可以设计成如下图所示的样式,关于如何设计界面布局是前面讲过的内容,这里就不在重复。那么在这个界面包含的组件有:一个标签、两个输入框、一个编辑框及四个按钮。这些组件如何生成,如何布局在界面上请查阅前面的文章。关键的是connect、flush及save三个按钮功能是如何实现的是需要我们研究的,尤其是connect按钮。改按钮点击后会由对应的myconnect槽函数来响应。
mywindow.h文件的内容如下:
上文我们提到客户端与服务器端的一次网络通信首先是由客户端发起连接的,并且上文有提到这个客户端的连接是由connect按钮的点击及其槽函数实现的。代码中我们也看到了,在myconnect函数中实质性的就是做了tcpsocket -> connectToHost (ip,port.toInt()); 这样一件事。根据函数参数中给定的ip、端口进行主动连接。至此我们了解了客户端与服务器端的一次网络通信到底是怎么产生的了。
当端口接收到数据时,QT会触发一个叫做readyRead的信号,该信号与myread槽函数进行了捆绑。也就是说当有数据来的时候myread函数会进行数据的接收及处理,该存放就存放该做处理做处理。我们要注意的用C语言实现网络编程时的读数据和QT实现的不同,C中的connect及读数据是一种阻塞型的,而QT中则是使用的信号与槽来解决。因为在QT中不允许使用阻塞因此也就不需要考虑多线程了。好了到这里我们的QT网络通信的介绍就告一段落了。下面展示一下在PC上测试客户端和服务器端程序情形的图片作为本专题的结束。
By:霜月孤鸟
2014.8
上一篇文章,我们实现了服务器端程序的编写,首先创建一个服务器对象,然后使其处于监听的状态,当有新连接过来时,进行与新连接的连接工作。连接使用的是套接字socket类实现的对象,通过该类的write方法,定时1S发送数据到连接上的客户端。我们从中可以看出,这次网络通信首先是有客户发起的,那么客户端是怎么发送这个连接的了,以及连接成功后怎么接收或发送数据的?这就是本篇要讲解的内容。
首先我们要先设计好客户端的界面布局。可以设计成如下图所示的样式,关于如何设计界面布局是前面讲过的内容,这里就不在重复。那么在这个界面包含的组件有:一个标签、两个输入框、一个编辑框及四个按钮。这些组件如何生成,如何布局在界面上请查阅前面的文章。关键的是connect、flush及save三个按钮功能是如何实现的是需要我们研究的,尤其是connect按钮。改按钮点击后会由对应的myconnect槽函数来响应。
mywindow.h文件的内容如下:
#include "mywindow.h" mywindow::mywindow(){ tcpsocket = new QTcpSocket; label = new QLabel("Server IP:"); ledit_ip = new QLineEdit; ledit_ip->setInputMask("000.000.000.000;"); ledit_ip->setText("192.168.7.200"); ledit_port = new QLineEdit; ledit_port->setText("7070"); button_connect = new QPushButton("connect"); button_flush = new QPushButton("flush"); button_save = new QPushButton("save"); button_quit = new QPushButton("quit"); hlayout_1 = new QHBoxLayout; hlayout_2 = new QHBoxLayout; layout = new QVBoxLayout; tedit = new QTextEdit; hlayout_1->addWidget(label); hlayout_1->addWidget(ledit_ip); hlayout_1->addWidget(ledit_port); hlayout_1->addWidget(button_connect); hlayout_2->addWidget(button_flush); hlayout_2->addWidget(button_save); hlayout_2->addWidget(button_quit); layout->addLayout(hlayout_1); layout->addWidget(tedit); layout->addLayout(hlayout_2); setLayout(layout); connect(button_connect,SIGNAL(clicked()),this,SLOT(myconnect())); connect(button_quit,SIGNAL(clicked()),qApp,SLOT(quit())); connect(tcpsocket,SIGNAL(connected ()),this,SLOT(mytt())); connect(tcpsocket,SIGNAL(readyRead()),this,SLOT(myread())); connect(button_flush,SIGNAL(clicked()),this,SLOT(myflush())); connect(button_save,SIGNAL(clicked()),this,SLOT(mysave())); } void mywindow::mysave(void) { QString name; name = QFileDialog::getSaveFileName(); if(name.count() <= 0){ QMessageBox::about(this,"save:","file name!!!"); return ; } QFile file(name); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return; QTextStream out(&file); out << tedit->toPlainText (); } void mywindow::myflush(){ tedit->clear(); } void mywindow::myread(void){ QString tmp; int i; QTime tt; tt = QTime::currentTime (); QString time_str; time_str = tt.toString("hh:mm:ss"); UART_Format uformat; tcpsocket->read((char *)&uformat,(quint64)sizeof(uformat)); tmp.append(time_str); tmp.append(" "); tmp.append(QString::number (uformat.Header_1,16)); //cc ee tmp.append(" "); tmp.append(QString::number (uformat.Header_2,16)); //ee cc tmp.append(" "); tmp.append(QString::number (uformat.NodeSeq,16)); //模块序列 01 01 tmp.append(" "); tmp.append(QString::number (uformat.NodeID,16)); //模块ID (00表示网关) DeviceAddrList Motor == 9 tmp.append(" "); tmp.append(QString::number (uformat.Command,16)); //功能 01 dd tmp.append(" "); for(i = 0; i < 10; i++){ tmp.append(QString::number (uformat.Data[i],16)); //无用 保存节点的数据 tmp.append(" "); } tmp.append(QString::number (uformat.Tailer,16)); //ff tmp.append(" "); tedit->append(tmp); } void mywindow::myconnect(void) { //ip port QString ip; QString port; ip = ledit_ip->text(); port = ledit_port->text(); qDebug() << ip; qDebug() << port; tcpsocket -> connectToHost (ip,port.toInt()); } void mywindow::mytt(void) { QMessageBox::about(this,"title:","connected!!!"); }
上文我们提到客户端与服务器端的一次网络通信首先是由客户端发起连接的,并且上文有提到这个客户端的连接是由connect按钮的点击及其槽函数实现的。代码中我们也看到了,在myconnect函数中实质性的就是做了tcpsocket -> connectToHost (ip,port.toInt()); 这样一件事。根据函数参数中给定的ip、端口进行主动连接。至此我们了解了客户端与服务器端的一次网络通信到底是怎么产生的了。
当端口接收到数据时,QT会触发一个叫做readyRead的信号,该信号与myread槽函数进行了捆绑。也就是说当有数据来的时候myread函数会进行数据的接收及处理,该存放就存放该做处理做处理。我们要注意的用C语言实现网络编程时的读数据和QT实现的不同,C中的connect及读数据是一种阻塞型的,而QT中则是使用的信号与槽来解决。因为在QT中不允许使用阻塞因此也就不需要考虑多线程了。好了到这里我们的QT网络通信的介绍就告一段落了。下面展示一下在PC上测试客户端和服务器端程序情形的图片作为本专题的结束。
By:霜月孤鸟
2014.8
相关文章推荐
- 黑马程序员--10.网络编程--06.【Clinet_Server通信原理】【TCP_客户端和服务端会话】【阻塞式方法的详解】
- QT编程系列9--服务器端的网络编程
- 黑马程序员--10.网络编程--07.【C_S编程中服务器端和客户端的读写流】【C_S常见的“双卡”现象和解决--TCP文本转换器示例】【TCP文本转换器客户端和服务器端循环结束分析】【网络流简化】
- QT编程系列11--Qt网络编程的补充(一)
- 26-网络编程-10-网络编程(TCP协议-客户端)
- 黑马程序员--10.网络编程--05.【TCP协议相关类】【InetSocketAddress类】【Socket类】【ServerSocket类】【TCP客户端和服务器端】
- Java基础知识强化之网络编程笔记10:TCP之客户端读取文本文件服务器控制台输出
- 《visual c#.net网络核心编程》学习笔记系列之:获取本地主机信息
- perl网络编程学习系列:Net:FTP
- 深入Atlas系列:客户端网络访问基础结构示例(1) - 编写并使用自定义的WebRequestExecutor
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现
- Linux网络编程-简单的客户端和服务器通讯程序开发入门(2)
- 《visual c#.net网络核心编程》学习笔记系列之:常用的数据类型
- 创建电信网络实时监控图――电信网管中的Java客户端系列(四)
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现
- 网络-两远程客户端之间的通讯原理-Java基础-Java-编程开发
- 网络编程 客户端 服务端 函数 流程 图示 来自深入理解计算机系统一书 P704
- 深入Atlas系列:客户端网络访问基础结构(下) - WebRequestExecutor和XMLHttpExecutor
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现
- 【Windows编程】【网络编程】【基于网络端口通信的客户端应用程序】解决方案【示意程序】