3.QT使用http协议通信
1. Qt6使用http协议在客户端发送一条文字消息到服务器端。
1.httpserver
main.cpp
1
2
3
4
5
6
7
8
9
10
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
HttpServer server;
return a.exec();
}httpserver.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class HttpServer : public QObject
{
Q_OBJECT
public:
explicit HttpServer(QObject *parent = nullptr);
private slots:
void onNewConnection();
void onReadyRead();
private:
QTcpServer *server;
};httpserver.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
HttpServer::HttpServer(QObject *parent)
: QObject(parent),
server(new QTcpServer(this))
{
// 使用 Any 同时监听 IPv4 和 IPv6(系统支持时)
if (server->listen(QHostAddress::Any, 8080)) {
qDebug() << "HTTP Server listening on port 8080 (IPv4 & IPv6 if supported)";
} else {
qDebug() << "Failed to start HTTP server";
}
connect(server, &QTcpServer::newConnection,
this, &HttpServer::onNewConnection);
}
void HttpServer::onNewConnection()
{
QTcpSocket *socket = server->nextPendingConnection();
connect(socket, &QTcpSocket::readyRead,
this, &HttpServer::onReadyRead);
}
void HttpServer::onReadyRead()
{
QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
if (!socket) return;
QByteArray request = socket->readAll();
qDebug() << "=== HTTP Request ===";
qDebug().noquote() << request;
// 简单解析 POST 数据
int idx = request.indexOf("\r\n\r\n");
if (idx != -1) {
QByteArray body = request.mid(idx + 4);
qDebug() << "Received body:" << QString::fromUtf8(body).trimmed();
}
// 返回 HTTP 响应
QByteArray response =
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"Content-Length: 2\r\n"
"\r\nOK";
socket->write(response);
socket->disconnectFromHost();
}CmakeList.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28cmake_minimum_required(VERSION 3.16)
project(httpserver LANGUAGES CXX)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Network)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Network)
add_executable(httpserver
main.cpp
httpserver.h httpserver.cpp
)
target_link_libraries(httpserver Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Network)
include(GNUInstallDirs)
install(TARGETS httpserver
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
2.httpclient
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
HttpClient client;
client.sendMessage(QUrl("http://127.0.0.1:8080"), "Hello from HTTP client via IPv4!");
// 或
client.sendMessage(QUrl("http://[::1]:8080"), "Hello from HTTP client via IPv6!");
return a.exec();
}httpclient.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class HttpClient : public QObject
{
Q_OBJECT
public:
explicit HttpClient(QObject *parent = nullptr);
void sendMessage(const QUrl &url, const QString &message);
private slots:
void onFinished(QNetworkReply *reply);
private:
QNetworkAccessManager manager;
};httpclient.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
HttpClient::HttpClient(QObject *parent)
: QObject(parent)
{
connect(&manager, &QNetworkAccessManager::finished,
this, &HttpClient::onFinished);
}
void HttpClient::sendMessage(const QUrl &url, const QString &message)
{
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain");
QByteArray data = message.toUtf8();
manager.post(request, data);
}
void HttpClient::onFinished(QNetworkReply *reply)
{
if (reply->error() == QNetworkReply::NoError) {
qDebug() << "Server response:" << reply->readAll();
} else {
qDebug() << "Error:" << reply->errorString();
}
reply->deleteLater();
}CmakeList.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27cmake_minimum_required(VERSION 3.16)
project(httpclient LANGUAGES CXX)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Network)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Network)
add_executable(httpclient
main.cpp
httpclient.h httpclient.cpp
)
target_link_libraries(httpclient Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Network)
include(GNUInstallDirs)
install(TARGETS httpclient
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
2. Qt6使用http协议在客户端发送多条文字消息到服务器端。
1.httpserver
main.cpp
1
2
3
4
5
6
7
8
9
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
HttpServer server;
return a.exec();
}httpserver.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class HttpServer : public QObject
{
Q_OBJECT
public:
explicit HttpServer(QObject *parent = nullptr);
private slots:
void onNewConnection();
void onReadyRead();
private:
QTcpServer *server;
};httpserver.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
HttpServer::HttpServer(QObject *parent)
: QObject(parent),
server(new QTcpServer(this))
{
// 使用 Any 同时监听 IPv4 和 IPv6(系统支持时)
if (server->listen(QHostAddress::Any, 8080)) {
qDebug() << "HTTP Server listening on port 8080 (IPv4 & IPv6 if supported)";
} else {
qDebug() << "Failed to start HTTP server";
}
connect(server, &QTcpServer::newConnection,
this, &HttpServer::onNewConnection);
}
void HttpServer::onNewConnection()
{
QTcpSocket *socket = server->nextPendingConnection();
connect(socket, &QTcpSocket::readyRead,
this, &HttpServer::onReadyRead);
}
void HttpServer::onReadyRead()
{
QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
if (!socket) return;
QByteArray request = socket->readAll();
qDebug() << "=== HTTP Request ===";
qDebug().noquote() << request;
// 简单解析 POST 数据
int idx = request.indexOf("\r\n\r\n");
if (idx != -1) {
QByteArray body = request.mid(idx + 4);
qDebug() << "Received body:" << QString::fromUtf8(body).trimmed();
}
// 返回 HTTP 响应
QByteArray response =
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"Content-Length: 2\r\n"
"\r\nOK";
socket->write(response);
socket->disconnectFromHost();
}CmakeList.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28cmake_minimum_required(VERSION 3.16)
project(httpserver LANGUAGES CXX)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Network)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Network)
add_executable(httpserver
main.cpp
httpserver.h httpserver.cpp
)
target_link_libraries(httpserver Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Network)
include(GNUInstallDirs)
install(TARGETS httpserver
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
2.httpclient
main.cpp
1
2
3
4
5
6
7
8
9
10
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
HttpClient client;
client.start(QUrl("http://127.0.0.1:8080")); // 或 http://[::1]:8080
return a.exec();
}httpclient.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class HttpClient : public QObject
{
Q_OBJECT
public:
explicit HttpClient(QObject *parent = nullptr);
void start(const QUrl &url);
private slots:
void sendNextMessage();
void onFinished(QNetworkReply *reply);
private:
QNetworkAccessManager manager;
QTimer timer;
QStringList messages;
int currentIndex;
QUrl serverUrl;
};httpclient.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
HttpClient::HttpClient(QObject *parent)
: QObject(parent),
currentIndex(0)
{
connect(&manager, &QNetworkAccessManager::finished,
this, &HttpClient::onFinished);
connect(&timer, &QTimer::timeout,
this, &HttpClient::sendNextMessage);
// 要发送的多条消息
messages << "Hello HTTP Server!"
<< "This is message 2"
<< "Qt6 HTTP multi-message test"
<< "Goodbye!";
}
void HttpClient::start(const QUrl &url)
{
serverUrl = url;
timer.start(1000); // 每秒发送一条
}
void HttpClient::sendNextMessage()
{
if (currentIndex >= messages.size()) {
timer.stop();
qDebug() << "All messages sent.";
return;
}
QNetworkRequest request(serverUrl);
request.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain");
QByteArray data = messages[currentIndex].toUtf8();
manager.post(request, data);
qDebug() << "Sent:" << messages[currentIndex];
currentIndex++;
}
void HttpClient::onFinished(QNetworkReply *reply)
{
if (reply->error() == QNetworkReply::NoError) {
qDebug() << "Server response:" << reply->readAll();
} else {
qDebug() << "Error:" << reply->errorString();
}
reply->deleteLater();
}CmakeList.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27cmake_minimum_required(VERSION 3.16)
project(httpclient LANGUAGES CXX)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Network)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Network)
add_executable(httpclient
main.cpp
httpclient.h httpclient.cpp
)
target_link_libraries(httpclient Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Network)
include(GNUInstallDirs)
install(TARGETS httpclient
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
3.Qt6使用http协议在客户端发送消息后服务器返回消息与状态码
1.httpserver
main.cpp
1
2
3
4
5
6
7
8
9
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
HttpServer server;
return a.exec();
}httpserver.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class HttpServer : public QObject
{
Q_OBJECT
public:
explicit HttpServer(QObject *parent = nullptr);
private slots:
void onNewConnection();
void onReadyRead();
private:
QTcpServer *server;
};httpserver.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
HttpServer::HttpServer(QObject *parent)
: QObject(parent),
server(new QTcpServer(this))
{
if (server->listen(QHostAddress::Any, 8080)) {
qDebug() << "HTTP Server listening on port 8080";
} else {
qDebug() << "Failed to start HTTP server";
}
connect(server, &QTcpServer::newConnection,
this, &HttpServer::onNewConnection);
}
void HttpServer::onNewConnection()
{
QTcpSocket *socket = server->nextPendingConnection();
connect(socket, &QTcpSocket::readyRead,
this, &HttpServer::onReadyRead);
}
void HttpServer::onReadyRead()
{
QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
if (!socket) return;
QByteArray request = socket->readAll();
qDebug() << "=== HTTP Request ===";
qDebug().noquote() << request;
// 解析请求体
int idx = request.indexOf("\r\n\r\n");
QByteArray body;
if (idx != -1) {
body = request.mid(idx + 4).trimmed();
}
qDebug() << "Received body:" << QString::fromUtf8(body);
// 根据内容决定返回状态码
QByteArray statusLine;
QByteArray responseBody;
if (body.isEmpty()) {
statusLine = "HTTP/1.1 400 Bad Request\r\n";
responseBody = "Message body is empty";
} else {
statusLine = "HTTP/1.1 200 OK\r\n";
responseBody = "Server received: " + body;
}
QByteArray response;
response.append(statusLine);
response.append("Content-Type: text/plain\r\n");
response.append("Content-Length: " + QByteArray::number(responseBody.size()) + "\r\n");
response.append("\r\n");
response.append(responseBody);
socket->write(response);
socket->disconnectFromHost();
}CmakeList.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28cmake_minimum_required(VERSION 3.16)
project(httpserver LANGUAGES CXX)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Network)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Network)
add_executable(httpserver
main.cpp
httpserver.h httpserver.cpp
)
target_link_libraries(httpserver Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Network)
include(GNUInstallDirs)
install(TARGETS httpserver
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
2.httpclient
main.cpp
1
2
3
4
5
6
7
8
9
10
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
HttpClient client;
client.sendMessage(QUrl("http://127.0.0.1:8080"), "Hello from Qt6 HTTP client!");
return a.exec();
}httpclient.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class HttpClient : public QObject
{
Q_OBJECT
public:
explicit HttpClient(QObject *parent = nullptr);
void sendMessage(const QUrl &url, const QString &message);
private slots:
void onFinished(QNetworkReply *reply);
private:
QNetworkAccessManager manager;
};httpclient.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
HttpClient::HttpClient(QObject *parent)
: QObject(parent)
{
connect(&manager, &QNetworkAccessManager::finished,
this, &HttpClient::onFinished);
}
void HttpClient::sendMessage(const QUrl &url, const QString &message)
{
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain");
manager.post(request, message.toUtf8());
}
void HttpClient::onFinished(QNetworkReply *reply)
{
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString reason = reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
QByteArray body = reply->readAll();
qDebug() << "HTTP Status:" << statusCode << reason;
qDebug() << "Response body:" << QString::fromUtf8(body);
reply->deleteLater();
}CmakeList.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27cmake_minimum_required(VERSION 3.16)
project(httpclient LANGUAGES CXX)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Network)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Network)
add_executable(httpclient
main.cpp
httpclient.h httpclient.cpp
)
target_link_libraries(httpclient Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Network)
include(GNUInstallDirs)
install(TARGETS httpclient
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
