0


[Qt][Qt 网络][下]详细讲解

目录


1.TCP Socket

1.核心API概览

  • 核⼼类是两个:QTcpServerQTcpSocket
  • QTcpServer用于监听端口,和获取客户端连接 - listen(const QHostAddress&, quint16 port):绑定指定的地址和端⼝号,并开始监听 - 成员方法- 对标原⽣API:bind()``````和listen()- nextPendingConnection():从系统中获取到⼀个已经建⽴好的tcp连接 - 返回⼀个QTcpSocket,表⽰这个客⼾端的连接 - 通过这个socket对象完成和客⼾端之间的通信- 成员方法- 对标原⽣API:accept()- newConnection():有新的客⼾端建⽴连接好之后触发 - 信号- 类似于IO多路复用的通知机制
  • QTcpSocket⽤于客⼾端和服务器之间的数据交互 - readAll():读取当前接收缓冲区中的所有数据,返回QByteArray对象 - 成员方法- 对标原生API:read()- write(const QByteArray &):把数据写⼊socket中 - 成员方法- 对标原生API:write()- deleteLater():暂时把socket对象标记为⽆效,Qt会在下个事件循环中析构释放该对象 - 成员方法- 类似于"半⾃动化的垃圾回收"- readyRead():有数据到达并准备就绪时触发 - 信号- 类似于IO多路复⽤中的通知机制- disconnected():连接断开时触发 - 信号- 类似于IO多路复⽤中的通知机制

2.回显服务器

// 构造函数中{
    server =newQTcpServer(this);// 通过信号槽, 指定如何处理连接.connect(server,&QTcpServer::newConnection,this,&Widget::ProcessConnection);// 绑定并监听端口号if(!ret = server->listen(QHostAddress::Any,2333)){QMessageBox::critical(this,"服务器启动失败!", server->errorString());exit(1);}}voidWidget::ProcessConnection(){// 通过 server 拿到一个 socket 对象, 通过这个对象来和客户端进行通信
    QTcpSocket* clientSocket = tcpServer->nextPendingConnection();
    
    QString log ="["+ clientSocket->peerAddress().toString()+":"+QString::number(clientSocket->peerPort())+"] 客户端上线!";
    ui->listWidget->addItem(log);// 通过信号槽, 来处理客户端发来请求的情况connect(clientSocket,&QTcpSocket::readyRead,this,[=](){// a) 读取出请求数据,此处 readAll 返回的是 QByteArray, 通过赋值转成 QString
        QString request = clientSocket->readAll();// b) 根据请求处理响应const QString& response =Process(request);// c) 把响应写回到客户端
        clientSocket->write(response.toUtf8());// d) 把上述信息记录到日志中.
        QString log ="["+ clientSocket->peerAddress().toString()+":"+QString::number(clientSocket->peerPort())+"] "+" req: "+ request +", resp: "+ response;
        ui->listWidget->addItem(log);});// 通过信号槽, 来处理客户端断开连接的情况.connect(clientSocket,&QTcpSocket::disconnected,this,[=](){// a) 把断开连接的信息通过日志显示出来.
        QString log ="["+ clientSocket->peerAddress().toString()+":"+QString::number(clientSocket->peerPort())+"] 客户端下线!";
        ui->listWidget->addItem(log);// b) 手动释放 clientSocket. 直接使用 delete 是下策, 使用 deleteLater 更加合适
        clientSocket->deleteLater();});}

QString Widget::Process(const QString request){return request;}

3.回显客户端

// 构造函数中{
    socket =newQTcpSocket(this);// 服务器建立连接,此处是非阻塞的IO通信
    socket->connectToHost("127.0.0.1",2333);// 连接信号槽, 处理响应connect(socket,&QTcpSocket::readyRead,this,[=](){// a) 读取出响应内容
        QString response = socket->readAll();// b) 把响应内容显示到界面上.
        ui->listWidget->addItem("服务器说: "+ response);});// 等待连接建立的结果. 确认是否连接成功.if(!socket->waitForConnected()){QMessageBox::critical(this,"连接服务器出错", socket->errorString());exit(1);}}voidWidget::on_pushButton_clicked(){const QString& text = ui->lineEdit->text();
    
    socket->write(text.toUtf8());
    
    ui->listWidget->addItem("客户端说: "+ text);
    ui->lineEdit->setText("");}

2.HTTP Client

  • Qt只提供了Http客户端,并没有提供Http服务端的库
  • 关键类主要是三个:QNetworkAccessManager , QNetworkRequest , QNetworkReply
  • QNetworkAccessManager提供了HTTP的核⼼操作 - get(const QNetworkRequest&):发起⼀个HTTP GET请求,返回QNetworkReply对象 - 本身不是阻塞函数,只负责发出去请求,不负责等请求回来- 收是QNetworkReply负责的,会收到finished信号- post(const QNetworkRequest&, const QByteArray&):发起⼀个HTTP POST请求,返回QNetworkReply对象
  • QNetworkRequest表⽰⼀个HTTP请求(不含body),如果需要发送⼀个带有body的请求(⽐如post),会在QNetworkAccessManagerpost()中通过单独的参数来传⼊body - QNetworkRequest(const QUrl&):通过URL构造⼀个HTTP请求- setHeader(QNetworkRequest::KnownHeaders header, const QVariant& value):设置请求头 - QNetworkRequest::KnownHeaders是⼀个枚举类型,常⽤取值 - ContentTypeHeader:描述body的类型- ContentLengthHeader:描述body的⻓度- LocationHeader:⽤于重定向报⽂中指定重定向地址- CookieHeader:设置cookie- UserAgentHeader:设置User-Agent
  • QNetworkReply表⽰⼀个HTTP响应,这个类同时也是QIODevice的⼦类 - error():获取出错状态- errorString():获取出错原因的⽂本- readAll():读取响应body- header(QNetworkRequest::KnownHeaders header):读取响应指定header的值- finished():为一个信号,在客⼾端收到完整的响应数据之后触发
  • 示例// 构造函数中{ manager =newQNetworkAccessManager(this);}voidWidget::on_pushButton_clicked(){// 1. 获取到输入框中的 url QUrl url(ui->lineEdit->text());// 2. 构造一个 HTTP 请求对象 QNetworkRequest request(url);// 3. 发送请求 QNetworkReply* response = manager->get(request);// 4. 通过信号槽, 来处理响应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 进行手动释放. response->deleteLater();});}

3.其他模块

  • Qt中还提供了FTP,DNS,SSL等⽹络相关的组件⼯具,有需要可以具体学习,查阅官方文档
标签: qt 网络 C++

本文转载自: https://blog.csdn.net/qq_37281656/article/details/141277152
版权归原作者 DieSnowK 所有, 如有侵权,请联系我们删除。

“[Qt][Qt 网络][下]详细讲解”的评论:

还没有评论