QT实现客户端服务器HTTP(get请求、post请求)

这篇具有很好参考价值的文章主要介绍了QT实现客户端服务器HTTP(get请求、post请求)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

服务器代码如下:

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请求:

QT实现客户端服务器HTTP(get请求、post请求)

POST请求:

QT实现客户端服务器HTTP(get请求、post请求)

POST请求使用postman测试:

QT实现客户端服务器HTTP(get请求、post请求)

注意:可以发现,在使用postman进行POST请求发送时,服务器接收到的请求头与QTSocket的POST请求的请求头是不同的,这里的原因目前还没有想到很好的解释。其中QTSocket的请求是将所有的参数组合后放在了请求头的最后,所以程序中在进行POST解析时多了一种情况的解析。

另外服务端在接收请求时,使用readRedy()信号,会出现因为数据大小而导致的粘包,即客户端发送的请求,会触发一次或多次的readRedy()信号,这时就需要考虑判定服务器所接收的rely->readAll()是不是完整的。本例中主要用到的方法是根据info中是否包含”=“来确定的。

TODO:

当然更为健壮的一种方式应该是通过字节数来确定,请求是否完整。

需要考虑的是如何处理多线程,多请求异步发生。文章来源地址https://www.toymoban.com/news/detail-421191.html

到了这里,关于QT实现客户端服务器HTTP(get请求、post请求)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于Spring Boot2.0 & HTTP/2 实现服务器、客户端

    HTTP协议由于其无状态的特性以及超高的普及率,是当下大部分网站选择使用的应用层协议。然而,HTTP/1.x的底层传输方式的几个特性,已经对应用的整体性能产生了负面影响。特别是,HTTP/1.0在每次的TCP连接上只允许发送一次请求,在HTTP/1.1中增加了请求管线,但是这仅仅解决

    2023年04月09日
    浏览(68)
  • Qt 服务器/客户端TCP通讯

    最近需要用到TCP/IP通讯,这边就先找个简单的例程学习一下。Qt的TCP通讯编程可以使用QtNetwork模块,QtNetwork模块提供的类能够创建基于TCP/IP的客户端与服务端应用程序,一般会使用QTcpSocket、QTcpServer类 网络通信方式主要有两种:TCP与UDP。以下拷贝网络上总结两者之间的区别:

    2023年04月26日
    浏览(70)
  • Nginx HTTP/3服务器-客户端环境搭建

    一、 NGINX 服务器介绍: NGINX是一个高性能的开源Web服务器,也可用作反向代理服务器、负载均衡器和HTTP缓存。它由俄罗斯的程序员Igor Sysoev创建,并于2004年首次公开发布。NGINX的设计重点是高性能、高并发和低内存消耗,使其成为了现代Web架构中的关键组件之一。 NGINX的一些

    2024年03月11日
    浏览(58)
  • 20230904 QT客户端服务器搭建聊天室

    Ser Cli

    2024年02月09日
    浏览(39)
  • java代码构建简单http服务器和客户端

    初识http a、超文本传输 、应用层的面向对象的协议,概念介绍网上资源一大堆,关键是基于TCP/IP通信协议来传递数据。 b、一开始接触web项目,都是先接触的servlet,tomcat服务器默认实现的一套http规范,提供了基础服务和组件环境,直接拿到请求、构建正文、响应客户端 然而

    2024年02月10日
    浏览(50)
  • 使用Go语言的HTTP客户端和服务器

    使用Go语言进行HTTP客户端和服务器开发是一种高效且强大的方式。Go语言的标准库提供了对HTTP协议的全面支持,使得创建HTTP客户端和服务器变得简单。 首先,让我们来看一下如何创建一个简单的HTTP服务器。在Go中,可以使用 net/http 包来创建HTTP服务器。以下是一个简单的示例

    2024年01月16日
    浏览(49)
  • Qt多线程TCP服务器客户端传输文件

    TCP是面向连接的运输层协议。应用程序在使用TCP协议之前,必须先建立TCP连接。在传送数据完毕后,必须释放已经建立的TCP连接。 每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的(一对一)。 TCP提供可靠交付的服务。通过TCP 连接传送的数据,无差错、不丢失、不

    2024年02月13日
    浏览(55)
  • HTTP介绍 原理 消息结构 客户端请求 服务器响应 HTTP状态码

    HTTP协议 是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于万维网(www.world wide web)服务器传输超文本到本地浏览器的传送协议 HTTP 是基于TCP/IP(三次握手,四次挥手)通信协议来传输数据(HTML文件,图片文件,查询结果等) TCP:可靠的,丢包重传 UTP:不可靠的,直播,

    2024年02月05日
    浏览(55)
  • QT下的多线程TCP客户端和服务器

    qt下的QTcpSocket在同一个线程使用时没有问题的,但是如果进行跨线程,很容易出现问题。那么有什么方法可以跨线程进行使用吗? 答案是肯定的:使用QThread的movetothread可以完成扩线程接收。 首先是基于QTcpSocket的类 头文件tcpsocket.h 然后是cpp文件tcpsocket.cpp 再次基础上,创建

    2024年01月17日
    浏览(50)
  • HTTP Header定制,客户端使用Request,服务器端使用Response

     在服务器端通过request.getHeaders()是无效的,只能使用response.getHeaders()。  

    2024年02月16日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包