<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>C++ on Hifumiのブログ</title><link>https://cutegirl.mizuharahifumi.top/tags/c++/</link><description>Recent content in C++ on Hifumiのブログ</description><generator>Hugo -- gohugo.io</generator><language>ja-JP</language><lastBuildDate>Sat, 08 Aug 2026 22:14:00 +0900</lastBuildDate><atom:link href="https://cutegirl.mizuharahifumi.top/tags/c++/index.xml" rel="self" type="application/rss+xml"/><item><title>C++とWinSock2でHTTPサーバを自作してみよう！#0 ソケットとWinSockRuntime</title><link>https://cutegirl.mizuharahifumi.top/posts/cpp-server-1/</link><pubDate>Sat, 08 Aug 2026 22:14:00 +0900</pubDate><guid>https://cutegirl.mizuharahifumi.top/posts/cpp-server-1/</guid><description>&lt;h3 id="まえがき"&gt;まえがき
&lt;/h3&gt;&lt;p&gt;Pythonなどでならコマンド1行だけ打てば立ち上げられるHTTPサーバですが、それは実は非常に奥深いシステムであり、ネットワークを学ぶうえでの極めて重要な基礎となります。&lt;/p&gt;
&lt;p&gt;このシリーズでは、次のような最小構成のHTTPサーバを目指して行く流れとなります。&lt;/p&gt;
&lt;img src="https://cutegirl.mizuharahifumi.top/img/http-server-eg.png" alt="最小構成のHTTPサーバの構成図"&gt;
&lt;h3 id="ソケット"&gt;ソケット
&lt;/h3&gt;&lt;p&gt;ソケットは、ネットワーク通信のための「通信口」と考えられます。電話の喩えで考えるなら、IPアドレスとポートは「電話番号」、そしてソケットは「受話器」の役割にあたります。&lt;/p&gt;
&lt;img src="https://cutegirl.mizuharahifumi.top/img/http-server-socket-phone.png" alt="ソケットを受話器にたとえた図"&gt;
&lt;p&gt;&lt;em&gt;By GPT Image 2&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Windowsでソケットを扱いたい場合、&lt;code&gt;WinSock2.h&lt;/code&gt;というライブラリが必要となってきます。&lt;/p&gt;
&lt;p&gt;ソケットを使う前には &lt;code&gt;WSAStartUp&lt;/code&gt; という関数で初期化する必要があり、使い終わったら丁寧に &lt;code&gt;WSACleanup()&lt;/code&gt; を呼び出して掃除していく必要があります。そこを抜かすとよくないため、C++では &lt;strong&gt;RAII&lt;/strong&gt; という考え方で初期化とクリーンアップを扱います。&lt;/p&gt;
&lt;h3 id="raiiで実装するwinsockruntime"&gt;RAIIで実装するWinsockRuntime
&lt;/h3&gt;&lt;p&gt;RAIIは「Resource Acquisition Is Initialization」（リソース獲得は初期化である）の略記で、リソースの初期化とクリーンアップをオブジェクトの寿命に紐づけることで、非常に賢くかつ簡単にそれを管理できてしまうという手法です。&lt;/p&gt;
&lt;img src="https://cutegirl.mizuharahifumi.top/img/http-server-raii.png" alt="RAIIによるWinSockの初期化と終了処理の図"&gt;
&lt;p&gt;C++のオブジェクトは初期化時必ずその &lt;strong&gt;コンストラクタ&lt;/strong&gt; を呼び出し、破棄時必ずその &lt;strong&gt;デストラクタ&lt;/strong&gt; を呼び出すようにできています。よって &lt;code&gt;WSAStartUp&lt;/code&gt; をオブジェクトのコンストラクタ内で呼び出し、&lt;code&gt;WSACleanup()&lt;/code&gt;を同オブジェクトのデストラクタ内で呼び出せば、オブジェクトの寿命が終わるのと同時に必ずきれいにクリーンアップされます。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// winsock_runtime.h
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#pragma once
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;WinsockRuntime&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; WinsockRuntime();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;~&lt;/span&gt;WinsockRuntime();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; WinsockRuntime(&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; WinsockRuntime&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;) &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;delete&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; WinsockRuntime&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;operator&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; WinsockRuntime&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;) &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;delete&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// winsock_runtime.cpp
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;#34;winsock_runtime.h&amp;#34;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;WinSock2.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;stdexcept&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;WinsockRuntime&lt;span style="color:#f92672"&gt;::&lt;/span&gt;WinsockRuntime() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; WSADATA wsa_data{};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; result &lt;span style="color:#f92672"&gt;=&lt;/span&gt; WSAStartup(MAKEWORD(&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;), &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;wsa_data);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (result &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;throw&lt;/span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;runtime_error(&lt;span style="color:#e6db74"&gt;&amp;#34;WSAStartup failed: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; std&lt;span style="color:#f92672"&gt;::&lt;/span&gt;to_string(result));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;WinsockRuntime&lt;span style="color:#f92672"&gt;::~&lt;/span&gt;WinsockRuntime() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; WSACleanup();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="次回予告"&gt;次回予告
&lt;/h3&gt;&lt;p&gt;本記事では、ソケットとは受話器みたいなものと述べていました。実際のネット通信ではまさにサーバー側とクライアント側の両方がそれぞれ別のソケット（受話器）を持ち通信していくイメージとなります。&lt;/p&gt;
&lt;p&gt;次回では詳しくソケットの通信とクライアントソケットを取得する&lt;code&gt;TcpListener&lt;/code&gt;クラスの構築を扱います。&lt;/p&gt;
&lt;p&gt;いかにしてCの生&lt;code&gt;SOCKET&lt;/code&gt;をRAIIでラップして、そしていかにしてクライアント側のソケットを取得するのか。どうぞ次回もお楽しみに。&lt;/p&gt;</description></item></channel></rss>