在网络层的应用Tcp可以发Get请求,用的QTcpSocket,主要流程以下几步:
- 找个免费在线api接口,我找的是“http://jsonplaceholder.typicode.com/posts”,http默认端口是80,找个在线HTTP POST/GET接口测试工具测试下这个api接口,我的测试的网址是在线HTTP GET/POST模拟测试工具,测试api接口是通的,能从接口中Get到数据;
- QTcp先连接socket.connectToHost(url.host(), url.port(80)); 连接网站和端口号;
- QTcp::write数据,数据按照Http协议的Get结构发送数据,数据结构为
QString getRequest = "GET " + url.path().toUtf8() + "/ HTTP/1.1\r\n" "Host:" + url.host().toUtf8() + "\r\n" "Connection: close\r\n\r\n";
- 再等待QTcp::readyRead,QTcp::readAll全部数据
代码如下;
SocketInternetWidget.cpp
#include "SocketInternetWidget.h"
#include "ui_SocketInternetWidget.h"
#include <QDebug>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonValue>
SocketInternetWidget::SocketInternetWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::SocketInternetWidget)
{
ui->setupUi(this);
initConnect();
url = QUrl("http://jsonplaceholder.typicode.com/posts");
qDebug() << url.host() << url.port(80);
// 连接到远程服务器
qDebug() << "Connecting to the server...";
socket.connectToHost(url.host(), url.port(80)); // 用实际的IP地址和端口替换"example.com"和12345
}
SocketInternetWidget::~SocketInternetWidget()
{
delete ui;
}
void SocketInternetWidget::on_pushButton_clicked()
{
// 构造一个简单的HTTP GET请求报文
QString getRequest = "GET " + url.path().toUtf8() + "/ HTTP/1.1\r\n"
"Host:" + url.host().toUtf8() + "\r\n"
"Connection: close\r\n\r\n";
// 发送GET请求
qint64 success = socket.write(getRequest.toUtf8());
qDebug() << "socket.write." << success;
// QUrl url("http://example.com");
// sendGetRequest(url , data);
}
void SocketInternetWidget::slot_processConnected()
{
qDebug() << "Connected to host.";
}
void SocketInternetWidget::slot_processRead()
{
// 读取并输出服务器的响应
QByteArray socketBA = socket.readAll();
qDebug() << "Server says:" << socketBA;
// // 将QByteArray转换为QJsonDocument
// QJsonDocument jsonDoc = QJsonDocument::fromJson(socketBA);
// // 确保JSON文档是一个对象或数组
// if (!jsonDoc.isObject() && !jsonDoc.isArray()) {
// qDebug() << "JSON document is not an object or array";
// return ;
// }
// // 输出JSON对象到QDebug
// QJsonObject jsonObj = jsonDoc.object();
// qDebug() << jsonObj;
}
void SocketInternetWidget::slot_processError(QAbstractSocket::SocketError error)
{
qDebug() << "Socket error:" << error;
}
void SocketInternetWidget::initConnect()
{
// 连接到服务器的信号槽
connect(&socket, &QTcpSocket::connected, this , &SocketInternetWidget::slot_processConnected);
// 当接收到来自服务器的数据时
connect(&socket, &QTcpSocket::readyRead, this, &SocketInternetWidget::slot_processRead);
// 处理连接错误
connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slot_processError(QAbstractSocket::SocketError)));
}
void SocketInternetWidget::sendGetRequest(const QUrl &url, const QByteArray &data) {
// 建立连接
socket.connectToHost(url.host(), url.port(80));
if (!socket.waitForConnected(10000)) {
// 连接超时或失败
// socket.deleteLater();
return;
}
// 构建GET请求
QByteArray request;
request.append("GET " + url.path().toUtf8() + "?" + data + " HTTP/1.1\r\n");
request.append("Host: " + url.host().toUtf8() + "\r\n");
request.append("Connection: close\r\n\r\n");
// 发送请求
socket.write(request);
// // 接收响应
// while(socket.waitForReadyRead(30000)) {
// QByteArray response = socket.readAll();
// // 处理响应
// }
// socket.deleteLater();
}
void SocketInternetWidget::printJson(const QByteArray &byteArray) {
QJsonDocument jsonDoc = QJsonDocument::fromJson(byteArray);
if (jsonDoc.isObject()) {
QJsonObject jsonObj = jsonDoc.object();
qDebug() << "JSON Object:";
printJsonObject(jsonObj, 1);
} else if (jsonDoc.isArray()) {
QJsonArray jsonArray = jsonDoc.array();
qDebug() << "JSON Array:";
printJsonArray(jsonArray, 1);
} else {
qDebug() << "JSON is neither an object nor an array.";
}
}
void SocketInternetWidget::printJsonObject(const QJsonObject &jsonObj, int indentLevel) {
QString indent(indentLevel, ' ');
for (auto it = jsonObj.begin(); it != jsonObj.end(); ++it) {
qDebug() << indent << it.key() << ":";
const QJsonValue &value = it.value();
if (value.isObject()) {
printJsonObject(value.toObject(), indentLevel + 2);
} else if (value.isArray()) {
printJsonArray(value.toArray(), indentLevel + 2);
} else {
qDebug() << indent << value;
}
}
}
void SocketInternetWidget::printJsonArray(const QJsonArray &jsonArray, int indentLevel) {
QString indent(indentLevel, ' ');
for (int i = 0; i < jsonArray.size(); ++i) {
qDebug() << indent << i << ":";
const QJsonValue &value = jsonArray[i];
if (value.isObject()) {
printJsonObject(value.toObject(), indentLevel + 2);
} else if (value.isArray()) {
printJsonArray(value.toArray(), indentLevel + 2);
} else {
qDebug() << indent << value;
}
}
}
SocketInternetWidget.h
#ifndef SOCKETINTERNETWIDGET_H
#define SOCKETINTERNETWIDGET_H
#include <QWidget>
#include <QTcpSocket>
#include <QUrl>
namespace Ui {
class SocketInternetWidget;
}
class SocketInternetWidget : public QWidget
{
Q_OBJECT
public:
explicit SocketInternetWidget(QWidget *parent = 0);
~SocketInternetWidget();
private slots:
void on_pushButton_clicked();
void slot_processConnected();
void slot_processRead();
void slot_processError(QAbstractSocket::SocketError error);
private:
void initConnect();
void sendGetRequest(const QUrl &url, const QByteArray &data);
void printJson(const QByteArray &byteArray);
void printJsonObject(const QJsonObject &jsonObj, int indentLevel);
void printJsonArray(const QJsonArray &jsonArray, int indentLevel);
private:
Ui::SocketInternetWidget *ui;
// 创建一个QTcpSocket实例
QTcpSocket socket;
QUrl url;
QByteArray data = "";
};
#endif // SOCKETINTERNETWIDGET_H