服务器代码如下:
QtHttpForS.h
#pragma once
#include <QtWidgets/QWidget>
#include "ui_QtHttpForS.h"
QT_BEGIN_NAMESPACE
class QTcpServer;
class QTcpSocket;
QT_END_NAMESPACE
class QtHttpForS : public QWidget
{
Q_OBJECT
public:
QtHttpForS(QWidget *parent = Q_NULLPTR);
~QtHttpForS();
int SumNums(QVector<int> nums);
protected slots:
void newConnectionSlot();
void errorStringSlot();
void sendMsg();
private:
Ui::QtHttpForSClass ui;
QTcpServer *m_tcpServer;
QTcpSocket *m_tcpSocket;
QString m_SocketInfo;
};
QtHttpForS.cpp
#include "QtHttpForS.h"
#include <QTcpServer>
#include <QDebug>
#include <QTcpSocket>
#include <QJsonObject>
#include <QJsonDocument>
#include "QAbstractSocket"
#include "QStringList"
QtHttpForS::QtHttpForS(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
m_tcpServer = new QTcpServer(this);
m_tcpServer->listen(QHostAddress::Any, 8080);
connect(m_tcpServer, SIGNAL(newConnection()), this, SLOT(newConnectionSlot()));
connect(m_tcpServer, SIGNAL(acceptError(QAbstractSocket::SocketError)), this, SLOT(errorStringSlot()));
}
QtHttpForS::~QtHttpForS()
{
m_tcpServer->close();
}
void QtHttpForS::newConnectionSlot()
{
ui.textEdit->append("newConnectionSlot() called!");
m_tcpSocket = m_tcpServer->nextPendingConnection();
connect(m_tcpSocket, SIGNAL(readyRead()), this, SLOT(sendMsg()));
}
void QtHttpForS::errorStringSlot()
{
ui.textEdit->append(m_tcpServer->errorString());
//qDebug() << m_tcpServer->errorString();
}
void QtHttpForS::sendMsg()
{
QByteArray data = m_tcpSocket->readAll();
QString m_requestInfo = data;
m_SocketInfo += m_requestInfo;
if (m_requestInfo.indexOf("=")>0)
{
ui.textEdit->append(m_SocketInfo);
//qDebug() << m_requestInfo;
QStringList list = m_SocketInfo.split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
qDebug() << list;
if (!list.empty())
{
QStringList headlist = QString(list[0]).split(QRegExp("[ ]"));
QString m_requestMethod = headlist[0];
//ui.textEdit->append(m_requestMethod);
//qDebug() << m_requestMethod;
QStringList paramList;
QString params(headlist[1]);
if (QString(headlist[1]).size()>1)
{
paramList = QString(headlist[1]).split("/");
params = paramList[1];
}
if (m_requestMethod == "GET" && params[0] == '?')
{
params = params.mid(1);
QStringList numsList = params.split('&');
QVector<int> nums;
foreach(QString s, numsList) {
nums.append(s.split('=')[1].toInt());
};
qDebug() << nums;
int sum = SumNums(nums);
QString contentStr = "<html>"
"<head>"
"<title>"
"Hello"
"</title>"
"</head>"
"<body>"
"<h1>" + QString::number(sum) +
"</h1>"
"</body>"
"</html>";
//send msg
QString str = "HTTP/1.1 200 OK\r\n";
str.append("Server:nginx\r\n");
str.append("Content-Type:text/html;charset=UTF-8\r\n");
str.append("Connection:keep-alive\r\n");
str.append(QString("Content-Length:%1\r\n\r\n").arg(contentStr.size()));
str.append(contentStr);
m_tcpSocket->write(str.toStdString().c_str());
}
if (m_requestMethod == "POST")
{
if (params[0] == '?')
{
params = params.mid(1);
QStringList numsList = params.split('&');
QVector<int> nums;
foreach(QString s, numsList) {
nums.append(s.split('=')[1].toInt());
};
qDebug() << nums;
int sum = SumNums(nums);
QJsonObject res;
res.insert("sum", QJsonValue(sum));
QJsonDocument documentJson(res);
QString strJson(documentJson.toJson(QJsonDocument::Compact));
QByteArray dataArray = documentJson.toJson();
//send msg
QString str = "HTTP/1.1 200 OK\r\n";
str.append("Server:nginx\r\n");
str.append("Content-Type:application/json;charset=UTF-8\r\n");
str.append("Connection:keep-alive\r\n");
str.append(QString("Content-Length:%1\r\n\r\n").arg(strJson.size()));
str.append(strJson);
m_tcpSocket->write(str.toStdString().c_str());
}
else
{
params = list[list.size()-1];
QStringList numsList = params.split('&');
QVector<int> nums;
foreach(QString s, numsList) {
nums.append(s.split('=')[1].toInt());
};
qDebug() << nums;
int sum = SumNums(nums);
QJsonObject res;
res.insert("sum", QJsonValue(sum));
QJsonDocument documentJson(res);
QString strJson(documentJson.toJson(QJsonDocument::Compact));
QByteArray dataArray = documentJson.toJson();
//send msg
QString str = "HTTP/1.1 200 OK\r\n";
str.append("Server:nginx\r\n");
str.append("Content-Type:application/json;charset=UTF-8\r\n");
str.append("Connection:keep-alive\r\n");
str.append(QString("Content-Length:%1\r\n\r\n").arg(strJson.size()));
str.append(strJson);
m_tcpSocket->write(str.toStdString().c_str());
}
}
}
m_SocketInfo = "";
}
}
int QtHttpForS::SumNums(QVector<int> nums)
{
int res = 0;
foreach(int num, nums) {
res += num;
};
return res;
}
main.cpp
#include "QtHttpForS.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QtHttpForS w;
w.show();
return a.exec();
}
QtHttpForS.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QtHttpForSClass</class>
<widget class="QWidget" name="QtHttpForSClass">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
<height>400</height>
</rect>
</property>
<property name="windowTitle">
<string>QtHttpForS</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTextEdit" name="textEdit"/>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
<include location="QtHttpForS.qrc"/>
</resources>
<connections/>
</ui>
客户端代码:
QtHttpForC.h
#pragma once
#include <QtWidgets/QWidget>
#include "ui_QtHttpForC.h"
#include <QTcpServer>
class QtHttpForC : public QWidget
{
Q_OBJECT
public:
QtHttpForC(QWidget *parent = Q_NULLPTR);
~QtHttpForC();
private slots:
void on_pushButton_clicked();
private:
QButtonGroup *m_Buttongroup;
QTcpSocket *m_Socket;
private:
Ui::QtHttpForCClass ui;
};
QtHttpForC.cpp
#include "QtHttpForC.h"
#include <QButtonGroup>
#include <QTcpSocket>
#include <QNetworkRequest>
#include <QUrl>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QDebug>
#include <QJsonParseError>
#include <QJsonDocument>
#include <QJsonObject>
#include "QByteArray"
QtHttpForC::QtHttpForC(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
m_Buttongroup = new QButtonGroup(this);
m_Buttongroup->addButton(ui.radioButton, 1);
m_Buttongroup->addButton(ui.radioButton_2, 2);
ui.textEdit_addr->setText("127.0.0.1");
ui.textEdit_port->setText("8080");
m_Socket = new QTcpSocket();
}
QtHttpForC::~QtHttpForC()
{
}
void QtHttpForC::on_pushButton_clicked()
{
m_Socket->abort();
qDebug() << "Connetting....";
QNetworkRequest request;
QString scheme = "http";
QString serverAddr = ui.textEdit_addr->toPlainText();
QString port = ui.textEdit_port->toPlainText();
QString requestHeader = scheme + QString("://") + serverAddr + QString(":") + port;
if (m_Buttongroup->checkedId() == 1)
{
//获取对应的参数数据
QByteArray data;
data.append("a=");
data.append(ui.textEdit_parm_1->toPlainText().toUtf8());
data.append("&b=");
data.append(ui.textEdit_parm_2->toPlainText().toUtf8());
QNetworkAccessManager manager;
request.setUrl(QUrl(requestHeader));
request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
QNetworkReply *reply = manager.post(request, data);
QEventLoop eventLoop;
QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
//对请求的返回异常进行处理
QByteArray replyData = reply->readAll();
if (reply->error() != QNetworkReply::NoError) {
qDebug() << reply->error();
delete m_Socket;
}
ui.textEdit_res->setText(QString(replyData));
reply->deleteLater();
}
else
{
QString fullRequest = requestHeader + QString("/?a=%1&b=%2").arg(ui.textEdit_parm_1->toPlainText().toInt()).arg(ui.textEdit_parm_2->toPlainText().toInt());
request.setUrl(QUrl(fullRequest));
QNetworkAccessManager manager;
QNetworkReply *reply = manager.get(request);
QEventLoop eventLoop;
QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
//对请求的返回异常进行处理
if (reply->error() != QNetworkReply::NoError) {
qDebug() << reply->error();
delete m_Socket;
}
QByteArray replyData = reply->readAll();
ui.textEdit_res->setText(QString(replyData));
reply->deleteLater();
}
}
mian.cpp
#include "QtHttpForC.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QtHttpForC w;
w.show();
return a.exec();
}
QtHttpForC.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QtHttpForCClass</class>
<widget class="QWidget" name="QtHttpForCClass">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
<height>400</height>
</rect>
</property>
<property name="windowTitle">
<string>QtHttpForC</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QWidget" name="widget" native="true">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>80</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QWidget" name="widget_4" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>服务器地址:</string>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="textEdit_addr">
<property name="maximumSize">
<size>
<width>10000</width>
<height>30</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_3" native="true">
<property name="maximumSize">
<size>
<width>120</width>
<height>16777215</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>端口:</string>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="textEdit_port">
<property name="maximumSize">
<size>
<width>50</width>
<height>30</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_2" native="true">
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QRadioButton" name="radioButton">
<property name="text">
<string>POST</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButton_2">
<property name="text">
<string>GET</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="maximumSize">
<size>
<width>300</width>
<height>500</height>
</size>
</property>
<property name="text">
<string>发送请求</string>
</property>
<property name="default">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QWidget" name="widget_7" native="true">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>80</height>
</size>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QWidget" name="widget_5" native="true">
<property name="maximumSize">
<size>
<width>300</width>
<height>16777215</height>
</size>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>参数1:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QTextEdit" name="textEdit_parm_1">
<property name="maximumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1">
<widget class="QWidget" name="widget_6" native="true">
<property name="maximumSize">
<size>
<width>300</width>
<height>70</height>
</size>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>参数2:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QTextEdit" name="textEdit_parm_2">
<property name="maximumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QTextEdit" name="textEdit_res"/>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
<include location="QtHttpForC.qrc"/>
</resources>
<connections/>
</ui>
程序运行效果:
GET请求:
POST请求:
POST请求使用postman测试:
注意:可以发现,在使用postman进行POST请求发送时,服务器接收到的请求头与QTSocket的POST请求的请求头是不同的,这里的原因目前还没有想到很好的解释。其中QTSocket的请求是将所有的参数组合后放在了请求头的最后,所以程序中在进行POST解析时多了一种情况的解析。
另外服务端在接收请求时,使用readRedy()信号,会出现因为数据大小而导致的粘包,即客户端发送的请求,会触发一次或多次的readRedy()信号,这时就需要考虑判定服务器所接收的rely->readAll()是不是完整的。本例中主要用到的方法是根据info中是否包含”=“来确定的。
TODO:
当然更为健壮的一种方式应该是通过字节数来确定,请求是否完整。文章来源:https://www.toymoban.com/news/detail-421191.html
需要考虑的是如何处理多线程,多请求异步发生。文章来源地址https://www.toymoban.com/news/detail-421191.html
到了这里,关于QT实现客户端服务器HTTP(get请求、post请求)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!