当前位置: 首页 > 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

相关文章:

  • 解决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的蒙特卡洛仿真