当前位置: 首页 > news >正文

QT客户端发送HTTP请求此时服务器到底收到了哪些数据?

一个Http请求包括

请求行 请求头 空行 请求体 

下面是示例: 1,2,3,4分别代表上面的四个部分,我只是做了一些解析,具体可以结合代码

1. post / HTTP/1.1

2.GET请求头包括Host(主机名),user-agent(客户端标识符),connection:keep-alived长连接方式

2.如果是Post请求,还包含Content-Length Content-Type字段,这些字段QT中发送的时候都可2.以自己设定,也可以使用默认的,使用setheader设置预定义的这些字段,使用setRawHeader可以任意设定k-val;

3.空行

4.json数据/html数据/文本数据

QT客户端使用HTTP请求发送

下面代码在构造的时候向服务器发送了HTTP请求,服务器只需要准备一个套接字读取数据即可,

这样就知道了服务器收到哪些数据,以及后续应该这么解析这个HTTP请求。

下面的代码中,使用setHeader和setRawHeader可以设置请求的一些参数,不设定的话默认也会生成一些参数,比如Host,,user-agent,connection这些字段。可以自己更改代码然后查看服务器的变化。

#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include<QJsonDocument>
#include<QJsonObject>
#include<QUrl>
#include<QDebug>class HttpClient : public QObject
{Q_OBJECTpublic:HttpClient(QObject *parent = nullptr) : QObject(parent) {// 创建 QNetworkAccessManager 实例manager = new QNetworkAccessManager(this);// 连接信号槽,处理请求完成的响应connect(manager, &QNetworkAccessManager::finished, this, &HttpClient::onFinished);// 构造 HTTP 请求QUrl url("http://192.168.31.245:8080");  // 示例 URLQNetworkRequest request(url);// request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");//request.setHeader(QNetworkRequest::ContentLengthHeader,"13");request.setRawHeader("User-Agent", "MyApp/1.0");request.setRawHeader("HH--YY--PP", "i am fun");// 构建 JSON 数据QJsonObject json;json["title"] = "foo";json["body"] = "bar";json["userId"] = 1;QJsonDocument jsonDoc(json);QByteArray jsonData = jsonDoc.toJson();// 发送 POST 请求manager->post(request, jsonData);//manager->get(request);}private slots:// 处理服务器的响应void onFinished(QNetworkReply *reply) {if (reply->error() == QNetworkReply::NoError) {// 读取服务器响应的数据QByteArray responseData = reply->readAll();qDebug() << "Response data:" << responseData;} else {// 处理请求中的错误qDebug() << "Error:" << reply->errorString();}// 释放资源reply->deleteLater();}private:QNetworkAccessManager *manager;  // HTTP 管理器
};

服务器代码

下面的代码在本地ubantu 虚拟机运行,这里只需要实现read数据就可以,因为这里主要验证的是服务器收到的数据有哪些?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>   // 包含网络地址结构和函数
#include <sys/socket.h>  // socket 相关函数#define PORT 8080  // 定义服务器的监听端口
#define BUFFER_SIZE 5555// 定义缓冲区大小int main() {int server_fd, new_socket;  // 服务器的 socket 文件描述符和新连接的 socketstruct sockaddr_in address;  // 存储服务器地址int addrlen = sizeof(address);  // 地址长度char buffer[BUFFER_SIZE] = {0};  // 用于接收消息的缓冲区const char *message = "Hello from server";  // 服务器的响应消息// 创建 socket 文件描述符if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);}// 服务器地址结构配置address.sin_family = AF_INET;  // IPv4address.sin_addr.s_addr = INADDR_ANY;  // 绑定到所有可用的网络接口address.sin_port = htons(PORT);  // 转换端口为网络字节序// 绑定 socket 到指定端口和地址if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("bind failed");close(server_fd);exit(EXIT_FAILURE);}// 监听端口,最大等待队列长度为 3if (listen(server_fd, 3) < 0) {perror("listen failed");close(server_fd);exit(EXIT_FAILURE);}printf("Server is listening on port %d\n", PORT);// 接受来自客户端的连接if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {perror("accept failed");close(server_fd);exit(EXIT_FAILURE);}// 从客户端接收数据int valread = read(new_socket, buffer, BUFFER_SIZE);printf("Message from client:\n%s", buffer);// 关闭 socketclose(new_socket);close(server_fd);return 0;
}

收到的数据如下

  request.setRawHeader("User-Agent", "MyApp/1.0");request.setRawHeader("HH--YY--PP", "i am fun");

上面的代码可以任意设定请求头的字段,更加的灵活。

将QT注释的代码取消注释,即可更新ConTent-type字段,Lenth字段没设定的话可以自动填充,一般不用自己设定,只需要设定ConTent-type来告诉服务器请求头是什么类型的数据即可。

总结

        最后服务器收到这些数据,根据请求行的URI,这里是/路径下,如果是get请求,根据后面的参数即可找到对应的文件,比如是一个html网页的静态页面,直接返回这个静态的HTML页面就可以。如果是Post请求,那么就读取请求体的数据来做后续的业务处理,比如客户端的登录,解析出用户名,密码(可以自己加密)等去查询数据库,最后封装响应返回即可。


http://www.mrgr.cn/news/35492.html

相关文章:

  • 机器学习(贝叶斯算法,决策树)
  • 开源音乐分离器Audio Decomposition:可实现盲源音频分离,无需外部乐器分离库,从头开始制作。将音乐转换为五线谱的程序
  • 优惠券秒杀的背后原理
  • 利用 Vue.js 开发动态组件的实战指南
  • C#实现在windows上实现指定句柄窗口的指定窗口坐标点击鼠标左键和右键的详细情况
  • 【目标检测】【Ultralytics-YOLO系列】Windows11下YOLOV5人脸目标检测
  • 解决Mac 默认设置 wps不能双面打印的问题
  • yum库 docker的小白安装教程(附部分问题及其解决方案)
  • 翻译:openmax文档
  • 从 Oracle 集群到单节点环境(详细记录一次数据迁移过程)之一:生产环境与目标服务器详情
  • 今日指数项目之大盘指数功能实现
  • 每日算法1(快慢指针)
  • nginx如何拦截未经授权的跳转
  • BUUCTF [SCTF2019]电单车详解两种方法(python实现绝对原创)
  • Codeforces Global Round 19 D题 Yet Another Minimization Problem(推式子,01背包变形)
  • 模拟哈希表
  • LVGL第一篇-了解lvgl显示原理以及使用C++移植
  • Zookeeper
  • BERT训练环节(代码实现)
  • Seata分布式事务实践
  • Allegro视频去除走线的小方块
  • [linux][证书]证书导出公钥
  • 关于Python升级以后脚本不能运行的问题
  • LCR 028
  • 字符串哈希
  • 2-102基于matlab的蒙特卡洛仿真