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_OBJECT

public:
    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");  // 示例 URL
        QNetworkRequest 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 文件描述符和新连接的 socket
    struct 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;  // IPv4
    address.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);
    }

    // 监听端口,最大等待队列长度为 3
    if (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);

    // 关闭 socket
    close(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请求,那么就读取请求体的数据来做后续的业务处理,比如客户端的登录,解析出用户名,密码(可以自己加密)等去查询数据库,最后封装响应返回即可。

### 回答1: Qt是一个跨平台的开发框架,可以用于开发服务器端和客户端应用程序。要实现Qt服务器端向客户端发送数据,可以采用TCP/IP协议进行通信。 在服务器端,可以使用QTcpServer类来创建一个TCP服务器。首先,需要创建一个QTcpServer对象并进行绑定监听。在有客户端连接时,通过QTcpServer的newConnection()信号来处理连接请求。一旦连接建立,服务器端就会创建一个QTcpSocket对象用于与客户端进行通信。 在服务器端向客户端发送数据,可以使用QTcpSocket的write()函数。可以将要发送数据作为参数传递给write()函数,然后通过调用flush()函数将数据立即发送出去。服务器端可以通过与客户端建立的QTcpSocket对象来调用这些函数,发送相关的数据。 在客户端,首先需要创建一个QTcpSocket对象用于连接服务器端。使用connectToHost()函数将客户端服务器端进行连接。连接成功后,可以通过QTcpSocket的readyRead()信号来接收服务器发送数据收到服务器发送数据后,客户端可以通过QTcpSocket的readAll()函数来获取完整的数据。然后可以对数据进行处理,显示或者进行其他操作。 最后,在服务器端与客户端的通信完成后,需要断开连接。可以调用QTcpSocket的disconnectFromHost()函数来关闭与客户端的连接,同时还需调用QTcpServer的close()函数来停止监听。 综上所述,Qt服务器端向客户端发送数据的过程包括:创建和监听服务器端,处理客户端连接请求,发送数据客户端客户端接收数据,并处理数据,最后断开连接。通过上述步骤可以实现Qt服务器端向客户端发送数据的功能。 ### 回答2: Qt是一个跨平台的应用程序开发框架,提供了丰富的功能和类来帮助开发者快速、高效地构建应用程序。在Qt中,服务器端向客户端发送数据可以通过以下几个步骤实现: 1. 创建和初始化一个QTcpServer对象,用于监听客户端的连接。 2. 在服务器端,通过调用QTcpServer对象的listen()函数开始监听指定的IP地址和端口号。这将使服务器端处于等待连接状态。 3. 在连接建立时,服务器端的QTcpServer对象会发射newConnection()信号,我们可以连接这个信号到一个槽函数中,以便在客户端连接时执行特定的操作。 4. 在槽函数中,可以通过调用QTcpServer对象的nextPendingConnection()函数来获取一个QTcpSocket对象,用于和客户端进行通信。 5. 通过QTcpSocket对象的write()函数向客户端发送数据。这个函数接受一个字节数组作为参数,将数据发送客户端。 6. 如果需要保证数据完整性和稳定性,可以调用QTcpSocket对象的waitForBytesWritten()函数来等待数据发送完成。 以上就是通过Qt实现服务器端向客户端发送数据的基本步骤。在实际开发中还可以根据需求进行相应的拓展和优化,例如使用信号和槽机制来实现异步通信、使用多线程来处理客户端连接等。 ### 回答3: Qt是一种跨平台的应用程序框架,它不仅可以用于移动设备和桌面应用程序的开发,还可以用于服务器端的开发。在Qt服务器端向客户端发送数据时,可以通过以下步骤来实现: 1. 创建一个QTcpServer对象,用于监听客户端的连接请求。可以使用QTcpServer类提供的listen()函数来指定监听的端口。 2. 在QTcpServer的incomingConnection()槽函数中接收连接请求并创建一个QTcpSocket对象。可以使用QTcpServer类提供的nextPendingConnection()函数获取到客户端的套接字。 3. 在服务器端准备好要发送数据。可以使用QByteArray类来保存数据,也可以使用QString类将数据转换为字符串。 4. 调用QTcpSocket类提供的write()函数将数据发送客户端。可以将要发送数据作为write()函数的参数传入。 5. 在发送数据后,可以调用QTcpSocket类提供的flush()函数来确保数据已经全部发送出去。 6. 如果需要,可以关闭服务器客户端之间的连接。可以调用QTcpSocket类提供的disconnectFromHost()函数来关闭客户端的套接字。 以上就是一个简单的Qt服务器端向客户端发送数据的过程。在实际的开发中,还可以根据具体的需求进行进一步的处理,如处理连接错误、处理客户端的请求等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值