기술나눔

Qt http 네트워크 프로그래밍

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

학습 목표: Qt HTTP 네트워크 프로그래밍

학습 콘텐츠

1. Http는 Hypertext Transfer Protocol의 약어로, 브라우저와 웹 서버 간의 통신 사양을 정의합니다. 일반적으로 TCP 위에서 실행되는 간단한 요청-응답 프로토콜입니다.

기능: WWW 서버와 브라우저 간의 정보 전송 사양을 규정하고 양 당사자가 준수하는 계약입니다.
2.http 작동 방식: HTTP는 클라이언트/서버 모델을 기반으로 하며 연결 ​​지향적입니다. HTTP 트랜잭션 프로세스

  1. 클라이언트는 서버와의 연결을 설정합니다.
  2. 클라이언트가 서버에 요청합니다.
  3. 서버는 요청을 수락하고 요청에 따른 응답으로 해당 파일을 반환합니다.
  4. 클라이언트와 서버가 연결을 닫습니다.

Qt는 두 가지 방법으로 HTTP 작업을 구현합니다.

1. QNetworkAccessManager 및 QNetworkReply 클래스를 사용하십시오.

  1. - QNetworkAccessManager는 HTTP/HTTPS 요청 전송 및 수신을 담당하는 Qt의 네트워크 액세스 관리자입니다.
  2. - QNetworkAccessManager::get/post 등을 통해 GET/POST 및 기타 요청을 시작하고 QNetworkReply 객체를 반환합니다.
  3. - QNetworkReply에서 응답 코드, 헤더 정보, 콘텐츠 등을 얻습니다. 동기식 및 비동기식 요청을 구현합니다.

2. QHttpEngine 및 QHttpNetworkRequest/Reply 클래스 사용(하위 수준):

  1. - QHttpEngine은 HTTP 연결 관리 및 요청 처리를 담당합니다.
  2. - QHttpNetworkRequest를 사용하여 요청을 작성하고 QHttpEngine을 통해 보냅니다.
  3. - 반환된 QHttpNetworkReply를 구문 분석하여 응답을 얻습니다.

일반적으로 간단한 HTTP 작업의 경우 높은 수준의 QNetworkAccessManager 인터페이스를 사용하는 것으로 충분합니다. 일반적인 요구 사항을 편리하게 처리합니다.

HTTP 엔진 또는 요청/응답 세부 사항을 사용자 정의하는 등 하위 수준 제어가 필요한 경우 QHttpEngine과 같은 하위 수준 클래스를 사용할 수 있습니다.

즉, Qt는 완전한 HTTP 클라이언트 구현을 제공하며 개발자는 실제 요구에 따라 네트워크 통신 작업에 보다 적합한 인터페이스를 선택할 수 있습니다. 이는 Qt 애플리케이션 개발을 위한 좋은 지원을 제공합니다.

요약하다:

첫 번째 유형: QNetworkAccessManager 네트워크 연결 관리자, 2개 작업: 요청을 얻거나 제출하기 위한 get/post, 다양한 연결 정보가 포함된 QNetworkReply 객체 반환.

두 번째 유형: QHttpEngine은 연결 요청만 관리하고 요청 전송에 대한 책임은 없습니다.

  • QHttpNetworkRequest를 사용하여 요청을 작성하고 QHttpEngine을 통해 보냅니다.

  • 반환된 QHttpNetworkReply를 구문 분석하여 응답을 얻습니다.

프로젝트 효과 및 핵심 코드

http 리더

http 서버

핵심 코드

http 리더

  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3. #include <QMainWindow>
  4. #include <QtNetwork> // 提供编程TCP/IP客户端和服务器的类
  5. #include <QUrl> // 提供接口使用URLs
  6. QT_BEGIN_NAMESPACE
  7. namespace Ui { class MainWindow; }
  8. QT_END_NAMESPACE
  9. class MainWindow : public QMainWindow
  10. {
  11. Q_OBJECT
  12. public:
  13. MainWindow(QWidget *parent = nullptr);
  14. ~MainWindow();
  15. private slots:
  16. void on_pushButton_clicked();
  17. private:
  18. Ui::MainWindow *ui;
  19. QNetworkAccessManager* accesssMgr;
  20. };
  21. #endif // MAINWINDOW_H
  22. #include "mainwindow.h"
  23. #include "ui_mainwindow.h"
  24. MainWindow::MainWindow(QWidget *parent)
  25. : QMainWindow(parent)
  26. , ui(new Ui::MainWindow)
  27. {
  28. ui->setupUi(this);
  29. accesssMgr =new QNetworkAccessManager(this);
  30. QObject::connect(accesssMgr,QOverload<QNetworkReply*>::of(&QNetworkAccessManager::finished),this,
  31. [this](QNetworkReply* reply){
  32. QString read=reply->readAll();
  33. ui->textBrowser->setText(read);
  34. reply->deleteLater(); //释放
  35. });
  36. }
  37. MainWindow::~MainWindow()
  38. {
  39. delete ui;
  40. }
  41. void MainWindow::on_pushButton_clicked()
  42. {
  43. ui->label->setText("数据正在下载中,请耐心等待......");
  44. QString url=ui->textEdit->toPlainText();
  45. qDebug()<<url;
  46. accesssMgr->get(QNetworkRequest(QUrl(url)));
  47. }

http 서버

  1. #include "httpserver.h"
  2. HttpServer::HttpServer(QObject *parent) : QObject(parent)
  3. {
  4. server =new QTcpServer(this);
  5. //连接回调
  6. connect(server,&QTcpServer::newConnection,this,&HttpServer::MyselfNewConnectCalllSlot);
  7. //开始监听
  8. if(!server->listen(QHostAddress::Any,8088))
  9. {
  10. qDebug()<<"n致命错误:Web服务器没有启动,请重新检查!"<<endl;
  11. }
  12. else
  13. {
  14. qDebug()<<"n正常启动:Web服务器端口:8088,等待客户端连接......"<<endl;;
  15. }
  16. }
  17. void HttpServer::MyselfNewConnectCalllSlot(){
  18. socket = server->nextPendingConnection(); //获取连接
  19. while(!(socket->waitForReadyRead(100))); //等待套接字是否有可读数据。 一直阻塞线程等待,直到有可读数据到达套接字,或者超时返回。
  20. QString webdata;
  21. webdata.resize(1000);
  22. webdata=socket->read(1000);
  23. qDebug()<<"正常运行:从浏览器读取数据信息......"<<webdata;
  24. //封装http协议
  25. socket->write("HTTP/1.1 200 OKrn");
  26. socket->write("Content-Type: text/htmlrn");
  27. socket->write("Connection: closern");
  28. socket->write("Refresh: 3rnrn"); // 每秒刷新Web浏览器
  29. socket->write("<!DOCTYPE>"
  30. "<html>"
  31. "<header>"
  32. "<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>"
  33. "<title>HttpServer</title>"
  34. "</header>"
  35. "<body>客户端已经连接HttpSever服务器秒数为:");
  36. QByteArray byte;
  37. static qint16 icount=0;
  38. byte.setNum(icount++);
  39. socket->write(byte);
  40. socket->write("</html>");
  41. /*
  42. flush() 不会等待数据真正发送出去,只是把数据从本地缓冲区 flush 到内核缓冲区。
  43. 如果输出缓冲区没有数据,flush() 有可能不做任何操作。
  44. 调用 flush() 可以确保目前为止写到 socket 的所有数据都发送给对端,而不是 buffered 在本地。
  45. 一般在发送完请求或应答后调用,保证数据及时发送出去。
  46. */
  47. socket->flush(); //刷新 socket 对象的输出缓冲区。 并发送
  48. connect(socket, &QTcpSocket::disconnected, socket, &QTcpSocket::deleteLater);
  49. socket->disconnectFromHost();
  50. }

 

요약하다

http는 tcp 기반의 애플리케이션 계층 프로토콜이므로 tcp 클래스가 사용되며 프로토콜 캡슐화가 수정되었습니다.주요 멤버 기능 디자인

  1. 请求:
  2. GET /index.html HTTP/1.1
  3. Host: www.example.com
  4. User-Agent: Mozilla/5.0...
  5. Accept: text/html
  6. 响应:
  7. HTTP/1.1 200 OK
  8. Date: Mon, 27 Jan 2020 08:12:31 GMT
  9. Server: Apache/2.4.1 (Unix)
  10. Last-Modified: Wed, 22 Jul 2020 19:15:56 GMT
  11. ETag: "49092-5b6-52c65aa32f280"
  12. Accept-Ranges: bytes
  13. Content-Length: 438
  14. Connection: close
  15. Content-Type: text/html; charset=UTF-8
  16. <html>
  17. <head>
  18. <title>Welcome to example.com!</title>
  19. </head>
  20. <body>
  21. <h1>Hello World!</h1>
  22. <p>This is the hello world page for an example website.</p>
  23. </body>
  24. </html>
  25. 这个示例演示了一个简单的HTTP请求和响应过程:
  26. 客户端发送GET请求获取index.html页面
  27. 服务器返回200状态码,表示请求成功
  28. 返回各种报头如日期、服务器信息等
  29. 返回HTML页面内容作为响应体

 

Qt HTTP 프로그래밍의 주요 클래스는 QNetworkAccessManager, QNetworkRequest 및 QNetworkReply입니다.

QNetworkAccessManager:

  • 네트워크에 대한 연결 및 요청을 관리합니다. 데이터를 보내고 받습니다.

  • HTTP 요청을 시작하기 위해 get(), post() 및 put()과 같은 고급 기능을 제공합니다.

  • 신호: finished(), authenticationRequired() 등.

QNetworkRequest:

  • HTTP 요청을 나타냅니다. URL 및 헤더와 같은 속성을 포함합니다.

  • 요청 방법, 콘텐츠 유형, 헤더 정보 등을 설정합니다.

QNetwork답변:

  • HTTP 응답을 나타냅니다. 상태 코드와 내용을 반환합니다.

  • 신호: downloadProgress(), error() 등 처리 결과를 알립니다.

  • readAll()과 같은 기능적 함수는 응답 내용을 읽습니다.

주요 단계:

  1. QNetworkAccessManager 객체 인스턴스를 만듭니다.

  2. QNetworkRequest 객체를 생성하여 URL과 속성을 설정하십시오.

  3. QNetworkAccessManager::get() 또는 post()와 같은 함수를 호출하여 요청합니다.

  4. 결과를 얻으려면 QNetworkReply의 신호를 들어보십시오.

  5. QNetworkReply를 통해 콘텐츠를 읽거나 오류를 처리합니다.

  6. 메모리 누수를 방지하려면 QNetworkReply 및 요청 객체를 제거하십시오.

마지막으로 소스코드 링크를 첨부해주세요
도움이 되셨다면 별점 부탁드려요

Qt 데모: Qt 프로세스 학습(gitee.com)