iTOP-4412全能版采用四核Cortex-A9,主频为1.4GHz-1.6GHz,配备S5M8767 电源管理,集成USB HUB,选用高品质板对板连接器稳定可靠,大厂生产,做工精良。接口一应俱全,开发更简单,搭载全网通4G、支持WIFI、蓝牙、陀螺仪、CAN总线、RS485总线、500万摄像头等模块,稳定运行Android 4.0.3/Android 4.4操作,系统通用Linux-3.0.15+Qt操作系统(QT支持5.7版本),Ubuntu版本:12.04,接口智能分配 方便好用。
第七十九章 Qt网络编程
网络编程有TCP和UDP,TCP编程需要用到俩个类:QTcpServer和QTcpSocket。
区别 | ||
TCP | UDP | |
是否连接 | 面向连接 | 面向非连接 |
传输可靠性 | 可靠 | 不可靠 |
应用场合 | 少量数据,如传输文件 | 传输大量数据,如传输视频语音 |
79.1 TCP实现服务器和客户端
TCP协议(Transmission Control Protocol)是一种面向连接的,可靠的,基于字节流的传输层通信协议,传输数据稳定可靠。
在 help索引中搜索到如图 两个重要类:
服务器编程中两个类都会用到,客户端编程中只会用到QTcpSocket对象。
本实验中对QTcpServer类的基本使用:
(1)监听客户端连接。
(2)每当有新的客户端连接服务器的时候,会自动触发信号,
(3)根据当前连接上的新的客户端创建一个Socket对象,将数据的收发动作交给socket套 接字去处理。
(4)关闭服务器close();
对QTcpSocket类的基本使用:
(1)服务器端:有新连接时获取连接状态,绑定socket 。
(2)客户端:通过socket连接服务器,连接成功触发信号。
(3)当有数据到来时会触发信号,用readAll()读取。
(4)通过读写socket收发数据。
具体步骤:
步骤一:创建工程,在工程文件.pro中添加network,如图:
步骤二:设计ui界面,
- 在属性编辑栏设置主窗口大小:
- 添加组件
接收窗口: Plain Text Edit
发送窗口,IP地址窗口,端口号窗口:Line Edit
打开服务器,关闭服务器:Push Button
拖拽完成后逐个布局,根据需要设置组件大小,这里端口号框设置成了最小200
按钮布局:拖拽按钮和弹簧,然后点击水平布局。
然后选中全部组件,点击栅格布局:
最后更改组件名称注释,完成后如图:
步骤三:服务器端编程:
1.创建QTcpServer对象
2.创建监听端口,使得客户端可以使用这个端口访问服务器,使用listen函数。
bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0);
第一个参数是绑定指定的地址(即本机服务器IP),第二个参数是绑定的本服务器端口号。
监听某个端口时,如果有新连接进来就发出newConnection()信号。
3.当服务器对象被访问时,会发出newConnection()信号,所以为该信号添加槽函数并用一个QTcpSocket对象接受客户端的访问。
4.当socket接受缓冲区有新数据到来时,会发出readyRead()信号,为该信号添加槽函数,使用readyRead()读取。
5.socket发送数据可直接调用write()成员函数。
6.关闭端口号。
代码如下:
#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>namespace Ui {
class TcpServer;
}class TcpServer : public QMainWindow
{Q_OBJECTpublic:explicit TcpServer(QWidget *parent = 0);~TcpServer();QTcpServer * tcpServer;QTcpSocket * tcpSocket;
public slots:void newConnection_Slot(void);void readyRead_Solt(void);
private slots:void on_openBu_clicked();void on_sendBu_clicked();void on_closeBu_clicked();private:Ui::TcpServer *ui;
};
#include "tcpserver.h"
#include "ui_tcpserver.h"
#include <QTcpServer>
#include <QTcpSocket>
#include <QString>
TcpServer::TcpServer(QWidget *parent) :QMainWindow(parent),ui(new Ui::TcpServer)
{ui->setupUi(this);tcpServer = new QTcpServer(this);tcpSocket = new QTcpSocket(this);//连接信号与槽函数进行绑定connect(tcpServer,SIGNAL(newConnection()),SLOT(newConnection_Slot()));
}//连接信号槽函数
void TcpServer::newConnection_Slot(void)
{//连接客户端后sockettcpSocket = tcpServer->nextPendingConnection();//套接字的接收数据信号与都数据槽函数连接connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_Solt()));
}
//读取数据
void TcpServer::readyRead_Solt(void)
{QString buf;//读取buf = tcpSocket->readAll();ui->recvEdit->appendPlainText(buf);
}TcpServer::~TcpServer()
{delete ui;
}//打开
void TcpServer::on_openBu_clicked()
{//监听tcpServer->listen(QHostAddress::Any,ui->portEdit->text().toUInt());
}//发送数据
void TcpServer::on_sendBu_clicked()
{tcpSocket->write(ui->sendEdit->text().toLocal8Bit().data());
}//关闭
void TcpServer::on_closeBu_clicked()
{tcpSocket->close();
}
步骤四:客户端编程
1.创建QTcpSocket套接字对象
2.使用套接字对象的成员函数去请求连接服务器。
void connectToHost(const QHostAddress &address, quint16 port, openMode mode = ReadWrite);
第一个参数为服务器IP地址,第二个参数为服务器端口号。第三个参数为打开方式,默认为可读可写
函数功能:请求连接服务器连接成功后发出connected()信号,绑定槽函数connected_Solt()去操作socket。
3.使用write函数向服务器发送数据,当socket接收缓冲区有新数据到来时
会发出readyRead()信号,为该信号添加槽函数以读取数据。
4.断开与服务器的连接。
class TcpClient : public QMainWindow
{
.......
private slots:void on_openBt_clicked();void connected_Solt(void);void readyRead_Solt(void);void on_sendEdit_2_clicked();void on_closeBt_clicked();
};TcpClient::TcpClient(QWidget *parent) :QMainWindow(parent),ui(new Ui::TcpClient)
{ui->setupUi(this);//创建socket 对象tcpSocket = new QTcpSocket(this);
}TcpClient::~TcpClient()
{delete ui;
}
//打开(连接服务器)
void TcpClient::on_openBt_clicked()
{tcpSocket->connectToHost(ui->ipEdit->text(),ui->portEdit->text().toUInt());connect(tcpSocket,SIGNAL(connected()),this,SLOT(connected_Solt()));
}
//等待数据到来
void TcpClient::connected_Solt(void)
{connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_Solt()));
}
//读取数据
void TcpClient::readyRead_Solt(void)
{ui->recvEdit->appendPlainText(tcpSocket->readAll());
}
//发送
void TcpClient::on_sendEdit_2_clicked()
{tcpSocket->write(ui->sendEdit->text().toLocal8Bit().data());
}
//关闭
void TcpClient::on_closeBt_clicked()
{tcpSocket->close();
}
编译运行成功,使用服务器和客户端通信如图 62.2.9.1.9:
79.2 UDP实现服务器和客户端
UDP协议是开放式,无连接,不可靠的传输层通信协议,但它收发数据的速度相对于TCP快很多,常用在传输音视频等数据量非常大的场合。
udp网络编程只需要使用一个类QUdpSocket。
本实验中对QUdpSocket的基本使用:
1.创建QUdpSocket对象。
2.绑定端口号
3.数据到来触发readyRead()信号。
4.读取发送数据。
5.关闭。
具体步骤:
步骤一:组装ui界面,和TCP章节搭建UI界面方法一致。
步骤二:编写代码
1.创建QUdpSocket对象,使用bind函数绑定端口号和套接字,数据报到来后会发出信 号readyRead(),在绑定的槽函数内去读取数据。
2.读取数据,数据到来hasPendingDatagrams()返回true,再用pendingDatagramSize()获取数据报的长度,如果数据没有被读取
完,hasPendingDatagrams()就会返回true,直至数据都被读取完。
readDatagram(data,size);
参数data为读取的数据,size为数据长度。
3.发送数据,使用writeDatagram函数,
writeDatagram(const char *data, qint64 len, const QHostAddress &host, quint16 port);
Data:发送的数据。
Len:发送的数据长度。
Host:目标IP地址。
Port:目标端口号。
4.关闭socket套接字。
代码如下:
udp.h
#include <QMainWindow>
#include <QUdpSocket>namespace Ui {
class Udp;
}class Udp : public QMainWindow
{Q_OBJECTpublic:explicit Udp(QWidget *parent = 0);~Udp();QUdpSocket * udpSocket;
private slots:void on_pushButton_clicked();void readyRead_Slot(void);void on_pushButton_3_clicked();void on_pushButton_2_clicked();private:Ui::Udp *ui;
};
udp.cpp:
Udp::Udp(QWidget *parent) :QMainWindow(parent),ui(new Ui::Udp)
{ui->setupUi(this);udpSocket = new QUdpSocket(this);
}Udp::~Udp()
{delete ui;
}
/** 打开按钮*/
void Udp::on_pushButton_clicked()
{//绑定本端口的端口号if(udpSocket->bind(ui->cliEdit->text().toUInt()) == true){QMessageBox::information(this,"提示","成功");}else{QMessageBox::information(this,"提示","失败");}//绑定数据信号和槽函数connect(udpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));
}
/**读取数据槽函数*/
void Udp::readyRead_Slot()
{QString buf;QByteArray array;//hasPendingDatagrams()返回true时表示至少有一个数据报在等待被读取while(udpSocket->hasPendingDatagrams()){//获取数据array.resize(udpSocket->pendingDatagramSize());udpSocket->readDatagram(array.data(),array.size());buf = array.data();ui->recvEdit->appendPlainText(buf);}
}/** 发送数据*/
void Udp::on_pushButton_3_clicked()
{quint16 port;QString sendBuff;QHostAddress address;address.setAddress(ui->ipEdit->text());//目标机地址port = ui->portEdit->text().toInt();//目标机端口号sendBuff = ui->sendEdit->text();//发送的数据//发送udpSocket->writeDatagram(sendBuff.toLocal8Bit().data(),sendBuff.length(),address,port);
}/**关闭*/
void Udp::on_pushButton_2_clicked()
{udpSocket->close();
}
步骤三:运行测试,收发功能正常如图: