个人主页~
Qt系统相关
一、Qt网络
在进行网络编程之前,需要在项目中的.pro文件中添加network模块
实际开发中不会用Qt直接写服务器的,因为服务器是没有图形化界面的,一般我们会用其他的语言软件写好程序之后与Qt联合使用,这里只是演示
在实现网络编程的时候在pro文件中要加入network
1、UDP Socket
(1)核心API
方法说明bind(const QHostAddress&,quint16)绑定指定的端口号receiveDatagram返回QNetworkDatagram,读取一个UDP数据报writeDatagram(const QNetworkDatagram&)发送一个UDP数据报信号说明readyRead在收到数据并准备就绪后触发
QNetworkDatagram
构造函数说明QNetworkDatagram(const QByteArray& ,const QHostAddress& ,quint16)通过QByteArray,目标IP地址,目标端口号构造一个UDP数据报方法说明data获取数据报内部持有的数据,返回QByteArraysenderAddress获取数据报中包含的对端的IP地址senderPort获取数据报中包含的对端的端口号
(2)回显服务器
回显服务器和回显客户端顾名思义就是我给服务器发送什么服务器给我发送什么
widget.cpp
Widget::Widget(QWidget *parent):QWidget(parent),ui(new Ui::Widget){
ui->setupUi(this);//修改窗口标题this->setWindowTitle("服务器");//创建udp实例
socket =newQUdpSocket(this);//连接信号槽connect(socket,&QUdpSocket::readyRead,this,&Widget::processRequest);//绑定端口bool ret = socket->bind(QHostAddress::Any,9090);if(!ret){QMessageBox::critical(nullptr,"服务器启动有误",socket->errorString());return;}}voidWidget::processRequest(){//读取请求const QNetworkDatagram& requestDatagram = socket->receiveDatagram();//解析请求
QString request = requestDatagram.data();//根据请求计算响应const QString& response =process(request);//响应回写客户端
QNetworkDatagram responseDatagram(response.toUtf8(),requestDatagram.senderAddress(),requestDatagram.senderPort());
socket->writeDatagram(responseDatagram);//交互信息显示到窗口上
QString log ="["+ requestDatagram.senderAddress().toString()+":"+QString::number(requestDatagram.senderPort())+"}req: "+request+",resp:"+response;
ui->listWidget->addItem(log);}
QString Widget::process(const QString &request){//对于回显服务器来说,请求就是回应,但是对于大型的商务服务器,这里的代码量是非常巨大的return request;}
(3)回显客户端
widget.cpp
const QString& SERVER_IP ="127.0.0.1";//客户端IP地址const quint16 SERVER_PORT =9090;//客户端端口号Widget::Widget(QWidget *parent):QWidget(parent),ui(new Ui::Widget){
ui->setupUi(this);//实例
socket =newQUdpSocket(this);//窗口名this->setWindowTitle("客户端");//信号槽连接connect(socket,&QUdpSocket::readyRead,this,&Widget::processResponse);}//这个函数用来处理收到的响应voidWidget::processResponse(){//读取解析响应const QNetworkDatagram& responseDatagram = socket->receiveDatagram();
QString response = responseDatagram.data();//因为是回显服务器,直接将响应数据显示到界面上
ui->listWidget->addItem("服务器:"+response);}voidWidget::on_pushButton_clicked(){//获取到输入框的内容 const QString& text = ui->lineEdit->text();//构造请求数据
QNetworkDatagram requestDatagram(text.toUtf8(),QHostAddress(SERVER_IP),SERVER_PORT);//发送请求数据
socket->writeDatagram(requestDatagram);//发送的请求添加到列表框
ui->listWidget->addItem("客户端:"+text);//清空输入框内容
ui->lineEdit->setText("");}
qudpsocket
2、TCP Socket
(1)核心API
主要有两个核心类
QTcpServer
方法说明listen(const QHostAddress&,quint16 port)绑定指定的地址和端口号,并开始监听nextPendingConnection从系统中获取到一个已经建立好的tcp连接,返回一个QTcpSocket,表示这个客户端的连接,通过这个socket对象完成和客户端之间的通信信号说明newConnection有新的客户端建立好之后触发
QTcpSocket
方法说明readAll读取当前接收缓冲区中的所有数据并返回一个QByteArray对象write(const QByteArray&)把数据写入socket中deleteLater暂时把socket对象标记为无效,Qt会在下个事件循环中析构释放该对象信号说明readyRead有数据到达准备就绪时触发disconnected断开连接时触发
(2)回显服务器
Widget::Widget(QWidget *parent):QWidget(parent),ui(new Ui::Widget){
ui->setupUi(this);// 1. 修改窗口标题.this->setWindowTitle("服务器");// 2. 创建 QTcpServer 的实例
tcpServer =newQTcpServer(this);// 3. 通过信号槽, 指定如何处理连接.connect(tcpServer,&QTcpServer::newConnection,this,&Widget::processConnection);// 4. 绑定并监听端口号. 一定要确保准备工作充分了, 再真正开张营业.// 这个操作得是初始化的最后一步. 都是需要把如何处理连接, 如何处理请求... 都准备好之后, 才能真正绑定端口并监听.bool ret = tcpServer->listen(QHostAddress::Any,9090);if(!ret){QMessageBox::critical(this,"服务器启动失败!", tcpServer->errorString());exit(1);}}Widget::~Widget(){delete ui;}voidWidget::processConnection(){//通过tcpServer获得socket对象, 通过这个对象来和客户端进行通信
QTcpSocket* clientSocket = tcpServer->nextPendingConnection();
QString log ="["+ clientSocket->peerAddress().toString()+":"+QString::number(clientSocket->peerPort())+"] 客户端上线!";
ui->listWidget->addItem(log);//通过信号槽, 来处理客户端发来请求的情况connect(clientSocket,&QTcpSocket::readyRead,this,[=](){//读取出请求数据. 此处 readAll 返回的是 QByteArray, 通过赋值转成 QString
QString request = clientSocket->readAll();//根据请求处理响应const QString& response =process(request);//把响应写回到客户端
clientSocket->write(response.toUtf8());//把上述信息记录到日志中
QString log ="["+ clientSocket->peerAddress().toString()+":"+QString::number(clientSocket->peerPort())+"] "+" req: "+ request +", resp: "+ response;
ui->listWidget->addItem(log);});//通过信号槽处理客户端断开连接情况connect(clientSocket,&QTcpSocket::disconnected,this,[=](){//断开连接信息通过日志打印
QString log ="["+ clientSocket->peerAddress().toString()+":"+QString::number(clientSocket->peerPort())+"] 客户端下线!";
ui->listWidget->addItem(log);//手动释放 clientSocket. 使用deleteLater更加合适
clientSocket->deleteLater();});}//回显服务器.
QString Widget::process(const QString request){return request;}
(3)回显客户端
Widget::Widget(QWidget *parent):QWidget(parent),ui(new Ui::Widget){
ui->setupUi(this);//设置窗口标题this->setWindowTitle("客户端");//创建socket实例
socket =newQTcpSocket(this);//和服务器连接
socket->connectToHost("127.0.0.1",9090);//连接信号槽, 处理响应connect(socket,&QTcpSocket::readyRead,[=](){// 读取出响应内容
QString response = socket->readAll();// 把响应内容显示到界面上
ui->listWidget->addItem("服务器说: "+ response);});// 等待连接建立的结果. 确认是否连接成功bool ret = socket->waitForConnected();if(!ret){QMessageBox::critical(this,"连接服务器出错", socket->errorString());exit(1);}}Widget::~Widget(){delete ui;}voidWidget::on_pushButton_clicked(){// 获取到输入框中的内容const QString& text = ui->lineEdit->text();// 发送数据给服务器
socket->write(text.toUtf8());// 把发的消息显示到界面上
ui->listWidget->addItem("客户端说: "+ text);// 清空输入框的内容
ui->lineEdit->setText("");}
qtcpsocket
3、HTTP Client
QNetworkAccessManager
提供核心操作
方法说明get(const QNetworkRequest& )发起一个HTTP GET请求,返回QNetworkReply对象post(const QNetworkRequest& ,const QByteArray& )发起一个HTTP POST请求,返回QNetworkReply对象
QNetworkRequest
表示一个HTTP请求,不含body,body是数据本体
方法说明QNetworkRequest(const QUrl& )通过URL构造一个HTTP请求setHeader(QNetworkRequest::KnowHeaders header,const QVariant& value)设置请求头
QNetworkReply
方法说明error获取出错状态errorString获取出错原因的文本readAll读取响应bodyheader(QNetworkRequest::KnownHeaders header)读取相应指定header的值
Widget::Widget(QWidget *parent):QWidget(parent),ui(new Ui::Widget){
ui->setupUi(this);
manager =newQNetworkAccessManager(this);}Widget::~Widget(){delete ui;}voidWidget::on_pushButton_clicked(){//获取到输⼊框中的URL, 构造QUrl对象
QUrl url(ui->lineEdit->text());//构造HTTP请求对象
QNetworkRequest request(url);//发送GET请求
QNetworkReply* response = manager->get(request);//通过信号槽来处理响应connect(response,&QNetworkReply::finished,this,[=](){if(response->error()== QNetworkReply::NoError){//响应正确
QString html(response->readAll());
ui->plainTextEdit->setPlainText(html);}else{//响应出错
ui->plainTextEdit->setPlainText(response->errorString());}
response->deleteLater();});}
qhttp
今日分享就到这里了~
版权归原作者 s_little_monster_ 所有, 如有侵权,请联系我们删除。