LoginSignup
5
3

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

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

5
3
1

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
  3. You can use dark theme
What you can do with signing up
5
3