HTTP プロトコルの概要
HTTP(HyperText Transfer Protocol)は、クライアントとサーバー間でリクエストとレスポンスを交換するためのプロトコルであり、通常は TCP 上で動作します。このプロトコルは、Web ブラウザとサーバー間の通信ルールを定義し、情報の送受信を標準化します。
HTTP の基本的な処理フローは以下の通りです:
- クライアントがサーバーとの TCP 接続を確立する。
- クライアントが HTTP リクエストを送信する。
- サーバーがリクエストを処理し、HTTP レスポンスを返す。
- 通信終了後に接続が切断される。
Qt を使った HTTP 実装例
1. HTTP クライアントの実装
Qt の QNetworkAccessManager を使用して、HTTP GET リクエストを送信し、レスポンスを取得するシンプルなクライアントアプリケーションです。
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QUrl>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_fetchButton_clicked();
void handleNetworkResponse(QNetworkReply *reply);
private:
Ui::MainWindow *ui;
QNetworkAccessManager *networkManager;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
networkManager = new QNetworkAccessManager(this);
connect(networkManager, &QNetworkAccessManager::finished,
this, &MainWindow::handleNetworkResponse);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_fetchButton_clicked()
{
ui->statusLabel->setText("データ取得中...");
QNetworkRequest request(QUrl("http://www.baidu.com"));
networkManager->get(request);
}
void MainWindow::handleNetworkResponse(QNetworkReply *reply)
{
if (reply->error() == QNetworkReply::NoError) {
ui->resultBrowser->setPlainText(reply->readAll());
} else {
ui->resultBrowser->setPlainText("エラー: " + reply->errorString());
}
reply->deleteLater();
}
2. 簡易 HTTP サーバーの実装
QTcpServer と QTcpSocket を使って、静的 HTML コンテンツを返す最小限の HTTP サーバーを構築します。
// httpserver.h
#ifndef HTTPSERVER_H
#define HTTPSERVER_H
#include <QObject>
#include <QTcpServer>
class HttpServer : public QObject
{
Q_OBJECT
public:
explicit HttpServer(QObject *parent = nullptr);
~HttpServer();
private slots:
void handleNewConnection();
private:
QTcpServer *tcpServer;
};
#endif // HTTPSERVER_H
// httpserver.cpp
#include "httpserver.h"
#include <QTcpSocket>
#include <QDateTime>
#include <QDebug>
HttpServer::HttpServer(QObject *parent)
: QObject(parent)
{
tcpServer = new QTcpServer(this);
connect(tcpServer, &QTcpServer::newConnection,
this, &HttpServer::handleNewConnection);
if (!tcpServer->listen(QHostAddress::Any, 8088)) {
qWarning() << "サーバー起動失敗:" << tcpServer->errorString();
} else {
qDebug() << "サーバーがポート 8088 で待機中...";
}
}
HttpServer::~HttpServer()
{
tcpServer->close();
}
void HttpServer::handleNewConnection()
{
static int visitCount = 0;
QTcpSocket *clientSocket = tcpServer->nextPendingConnection();
// リクエスト読み捨て(簡易実装のため)
clientSocket->waitForReadyRead(100);
clientSocket->readAll();
QString httpResponse =
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html; charset=utf-8\r\n"
"Refresh: 1\r\n"
"\r\n"
"<!DOCTYPE html>"
"<html>"
"<head><title>Qt HTTP Server</title></head>"
"<body>"
"<h2>Qt で実装した簡易 HTTP サーバー</h2>"
"<p>アクセス回数: " + QString::number(++visitCount) + "</p>"
"<p>現在時刻: " + QDateTime::currentDateTime().toString() + "</p>"
"</body>"
"</html>";
clientSocket->write(httpResponse.toUtf8());
clientSocket->flush();
clientSocket->disconnectFromHost();
connect(clientSocket, &QTcpSocket::disconnected,
clientSocket, &QTcpSocket::deleteLater);
}
// main.cpp
#include <QCoreApplication>
#include "httpserver.h"
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
HttpServer server;
return app.exec();
}