LoginSignup
2

C++ HTTPサーバー/クライアントを作る

Last updated at Posted at 2023-05-24

Google OSSのヘッダファイルを借りて、
HTTPサーバー/クライアントを作る。

概要

※2023/5/24時点の情報

簡単にhttpサーバー/クライアントを作る方法を調べた。
GoogleのchromiumOSのhttplib.hを借りると簡単に作れる。

以下がhttplib.hのリンク
chromium.googlesource.com/httplib.h

使い方は一つ上の階層に展開されている。
cpp-httplib/README.md

※補足(修正:2023/5/25)
@prickleさんから教えていただきました。
httplib.hはGoogle Chromeの作成物ではなく、yhiroseさんが作成したものを取り込んでいる。
https://github.com/yhirose/cpp-httplib

使い方のままであるが、一応サンプルアプリの作成手順を下記に残す。

手順

環境

以下の実行環境であることを前提にしている。

  • Linux or WSL2
  • Git
  • CMake

httplib.hのダウンロード/コピー

コピペでの手順

ローカルにhttplib.hのファイルを作り、コピペでリンクのソースをコピーする。

touch httplib.h

chromium.googlesource.com/httplib.hをコピーし、作成したファイルにペーストする。

ダウンロードでの手順

Gitがインストール済であることを前提に以下のコマンドを実施する。

git clone https://chromium.googlesource.com/crashpad/crashpad/
cp -p crashpad/third_party/cpp-httplib/cpp-httplib/httplib.h ./

サンプルアプリの作成

severSample.cppとclientSample.cppを作成する。

touch severSample.cpp
touch clientSample.cpp

ソースコードはそれぞれ以下のように記載する。
cpp-httplib/README.mdに書かれている内容からコンソールログを追加したぐらいのコード。

severSample.cpp

#include "httplib.h"
#include <iostream>

int main(void)
{
    using namespace httplib;
    Server svr;

    std::cout << "start Server" << std::endl;
    svr.Get("/hi", [](const Request& req, Response& res) {
        res.set_content("Hello World!", "text/plain");
    });

    svr.Get(R"(/numbers/(\d+))", [&](const Request& req, Response& res) {
        auto numbers = req.matches[1];
        res.set_content(numbers, "text/plain");
    });

    svr.listen("localhost", 1234);
}

clientSample.cpp

#include "httplib.h"
#include <iostream>

int main(void)
{
    httplib::Client cli("localhost", 1234);

    auto res = cli.Get("/hi");
    if (res && res->status == 200) {
        std::cout << res->body << std::endl;
    }
}

アプリのビルド

cmakeをインストール済であることを前提に、適当にCMakeLists.txtを作る。

CMakeLists.txt

cmake_minimum_required(VERSION 3.2 FATAL_ERROR)

# specify the C++ standard
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# set the project name and version
project(httpSample CXX)

# find package
find_package(Threads REQUIRED)

# compile executable file
add_executable(serverSample serverSample.cpp)
add_executable(clientSample clientSample.cpp)

# module, library, target link
target_link_libraries(serverSample PUBLIC "-pthread")
target_link_libraries(clientSample PUBLIC "-pthread")
  • Point!
    • 忘れてはいけないのは、threadをfind packageすること。
    • 見つけたpackageをtarget linkすること。
      • 理由はhttplib.h内でthread処理をしている。

ビルドを実行する。

mkdir build
cd build
cmake ..
make

buildフォルダ内に以下のファイルが生成される。

serverSample
clientSample

アプリの実行

コンソールを2つ用意する。
1つはserver用コンソール。もう1つはclient用コンソール。
それぞれのコンソールで以下を実行すると、HTTP通信ができる。

server用コンソール

$ ./serverSample 
start Server

client用コンソール

$ ./clientSample 
Hello World!

最後に

以上で終了です。
ソースコードの解説はありません。

severSample.cppについて、あえて触れるならば、

svr.Get("/hi", [](const Request& req, Response& res) {
    res.set_content("Hello World!", "text/plain");
});

"text/plain"は、HTTPヘッダのContent-Typeになります。
"text/plain"を指定して、clientへ"Hello World!"を送っています。

Content-Typeについてはググるとそれなりに出てきます。
Content-Type一覧は以下の記事が見やすかったです。
https://qiita.com/AkihiroTakamura/items/b93fbe511465f52bffaa

初投稿になりますが、ご参考になれば幸いです。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
2