{"id":5710,"date":"2026-05-18T10:30:51","date_gmt":"2026-05-18T01:30:51","guid":{"rendered":"https:\/\/www.freelifemakers.org\/wordpress\/?p=5710"},"modified":"2026-05-18T10:41:09","modified_gmt":"2026-05-18T01:41:09","slug":"basic-boost-asio-asio-tcp-echo-server","status":"publish","type":"post","link":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2026\/05\/18\/basic-boost-asio-asio-tcp-echo-server\/","title":{"rendered":"[Basic]Boost.Asio\/Asio Tcp echo Server"},"content":{"rendered":"\n<p>\ud83d\udc49\ud83c\udffb c++\uc758 Asio(\ub610\ub294 Bootst.asio) \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uc774\ud574\ud558\uae30 \uc704\ud55c \ucf54\ub4dc\uc785\ub2c8\ub2e4.<br>This is code to understand the C++ Asio (or Bootst.asio) library.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \uc544\ub798\uc758 \ucf54\ub4dc\ub294 \uc774\uc804\uc5d0 \uc5c5\ub85c\ub4dc\ud55c mini_mediaserver_1 \uc758  \uc77c\ubd80\ub85c\uc9c1\uc744 \uc0ac\uc6a9\ud569\ub2c8\ub2e4.<br>The code below uses some of the logic from the previously uploaded mini_mediaserver_1.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \ud14c\uc2a4\ud2b8 \ud658\uacbd\uc740 MacOS\uc785\ub2c8\ub2e4.<br>The test environment is MacOS.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb mini_mediaserver_1\uc740 standalone\ubc29\uc2dd\uc758 asio\ub97c \uc0ac\uc6a9\ud569\ub2c8\ub2e4.<br>mini_mediaserver_1 uses standalone asio.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \uc5ec\uae30\uc11c\ub294 Boosta.asio\ub97c\uc0ac\uc6a9\ud569\ub2c8\ub2e4.<br>Here, we use Boosta.asio.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \uc124\uce58 \ubc0f \uc0ac\uc6a9 \/ Install and Usage<\/p>\n\n\n\n<p>\u2714\ufe0f Boost.Asio \uc804\uccb4 \uc124\uce58 \/ full installation<\/p>\n\n\n\n<p>&#8212; \uc124\uce58 \/ Installatioon<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># macOS brew - boost.asio\nbrew install boost<\/code><\/pre>\n\n\n\n<p>&#8212; \uc0ac\uc6a9 \/ Usage<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include \"boost\/asio\" <\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f Asio Standalone<\/p>\n\n\n\n<p>&#8212; \uc124\uce58 \/ Installation<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># macOS brew - asio standalone\nbrew install asio<\/code><\/pre>\n\n\n\n<p>&#8212; \uc0ac\uc6a9 \/ Usage<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include \"asio.hpp\" <\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \ucf54\ub4dc \/ Code<\/p>\n\n\n\n<p>\u2714\ufe0f\ucf54\ub4dc \uc124\uba85 \/ Code Description<\/p>\n\n\n\n<p>&#8212; \ud568\uc218 \uc2e4\ud589 \ud750\ub984 \/ Function execution flow<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>main() -&gt; Server Class- &gt; do_accept() -&gt; Session Class -&gt; start { do_read {do_write()}}<\/code><\/pre>\n\n\n\n<p>&#8212; \uc18c\ucf13,\uc811\uc18d\uc815\ubcf4 \uacf5\uc720 \/ Socket, connection information sharing<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>1.\uc18c\ucf13\uc740 \ubcf5\uc0ac \ud560 \uc218 \uc5c6\uae30 \ub54c\ubb38\uc5d0 \uc18c\uc720\uad8c \uc774\ub3d9\uc744 \ud569\ub2c8\ub2e4.\nSince sockets cannot be copied, ownership is transferred.\n\nstd::make_shared&lt;Session&gt;(std::move(socket))-&gt;start();\n\n2.\uc811\uc18d \uc815\ubcf4\ub97c \uacf5\uc720\ud558\uae30 \uc704\ud574 \ub2e4\uc74c \ucf54\ub4dc\ub97c \uc0ac\uc6a9\ud569\ub2c8\ub2e4.\nUse the following code to share connection information.\n\n- make_shared\ub294 \ud558\ub098\ub9cc \uacf5\uc720\ud560 \uc218 \uc788\ub294 \ud3ec\uc778\ud130\ub97c \ub9cc\ub4ed\ub2c8\ub2e4.\nmake_shared creates a pointer that can be shared by only one person.\n\nstd::make_shared&lt;Session&gt;(std::move(socket))-&gt;start();\n\n- enable_shared_from_this\ub97c \uc0c1\uc18d\ubc1b\uc73c\uba74 shared_from_this(); \ud568\uc218\ub97c \uc0ac\uc6a9 \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\nIf you inherit from enable_shared_from_this, you can use the shared_from_this(); function.\n\npublic std::enable_shared_from_this&lt;Session&gt;\n\n- this(Session class) \uc815\ubcf4\uac00 \uc0ac\ub77c\uc9c8 \uc218 \uc788\uc5b4\uc11c \uc548\uc804\ud55c \uc5f0\uacb0\uc744 \uc704\ud574 self\uc5d0 Session Class \uc815\ubcf4\ub97c \ubcf5\ud558\ud569\ub2c8\ub2e4. \nSince the information in this (Session class) can be lost, the Session Class information is copied to self for a secure connection.\n\nauto self = shared_from_this();<\/code><\/pre>\n\n\n\n<p>&#8212;  echo<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>- \uc544\ub798\uc758 \ub78c\ub2e4 \ucf54\ub4dc\uc5d0\uc11c \uc18c\ucf13\uc5d0\uc11c \ubc1b\uc740 data_\uc758 \ub0b4\uc6a9\uc744 \ucd9c\ub825\ud558\uace0 \ub2e4\uc2dc \uc18c\ucf13\uc5d0 \ub370\uc774\ud130\ub97c \uc791\uc131\ud569\ub2c8\ub2e4.\nIn the lambda code below, the contents of data_ received from the socket are printed, and data is written back to the socket.\n\n&#91;this, self](boost::system::error_code ec, size_t len) {\n   if (!ec) {\n     std::cout &lt;&lt; \"\ubc1b\uc74c\/Receive: \" &lt;&lt; std::string(data_, len) &lt;&lt; \"\\n\";\n     do_write(len); \/\/ \uc5d0\ucf54 \/ echo\n   }\n});<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f\uc804\uccb4 \ucf54\ub4dc \/ Full Cdoe (tcpecho.cpp)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;iostream&gt;\n#include &lt;memory&gt;\n#include &lt;boost\/asio.hpp&gt;\nusing boost::asio::ip::tcp;\n\n\/\/ --\n\/*\n - std::make_shared&lt;Session&gt;(std::move(socket)) :\n   \ud55c \uacf3\ub9cc \ud3ec\uc778\ud130 \uacf5\uc720\uc124\uc815 \/ Pointer sharing settings for only one location\n\n - : public std::enable_shared_from_this&lt;Session&gt; :\n   shared_from_this(); \uc0ac\uc6a9\uc744 \uc704\ud574 \uc0c1\uc18d\n   Inheritance for using shared_from_this();\n\n - shared_from_this :\n   class Session \uac1d\uccb4\ub97c \ubcf5\uc0ac\ud574\uc11c \uc800\uc7a5\n   Copy and save the class Session object\n   ** this\uac00 \uc18c\uba78\ub420 \uc218 \uc788\uc5b4\uc11c \uc548\uc804\ud55c \uc138\uc158\uc5f0\uacb0 \uc720\uc9c0\ub97c \uc704\ud574 Session\ud074\ub798\uc2a4\ub97c \ud558\ub098 \ub354 \ubcf5\uc0ac\ud568\n      Since 'this' can be destroyed,\n      an additional copy of the Session class is made to maintain a safe session connection. **\n *\/\nclass Session : public std::enable_shared_from_this&lt;Session&gt; {\n    tcp::socket socket_;\n    char data_&#91;1024];\n\npublic:\n    Session(tcp::socket socket) : socket_(std::move(socket)) {}\n\n    void start() {\n        do_read();\n    }\n\nprivate:\n    void do_read() {\n\n        \/\/ \ub78c\ub2e4 \uc0b4\uc544\uc788\ub294 \ub3d9\uc548 Session \uc548 \uc8fd\uc74c \/ The Session does not die as long as Lambda is alive\n        \/\/ \uc774 \ud074\ub798\uc2a4 \uac1d\uccb4\ub97c \ubcf5\uc0ac\ud574\uc11c \uc800\uc7a5 \/ Copy and save this class object\n        auto self = shared_from_this();\n\n        \/*\n         * async_read_some(buffer(data_), \ub78c\ub2e4\/rambda)\n         * 1) \ub370\uc774\ud130 \uc624\uba74 data_\uc5d0 \ucc44\uc6cc\ub193\uace0 \ub78c\ub2e4 \uc2e4\ud589 \uc608\uc57d\ub9cc \ud55c\ub2e4.\n         * When data arrives, fill it into data_ and just schedule the Lambda execution.\n         *\n         * 2) OS\uac00 \uc18c\ucf13\uc5d0 \ub370\uc774\ud130 \ub4e4\uc5b4\uc624\ub294 \uac70 \uac10\uc9c0 \u2192 data_ \ubc30\uc5f4\uc5d0 len\ubc14\uc774\ud2b8\ub9cc\ud07c \ubcf5\uc0ac\ud574 \ub454\ub2e4.\n         * The OS detects incoming data in the socket and copies len bytes into the data_ array.\n         *\n         * 3) \ubcf5\uc0ac\uac00 \ub05d\ub0ac\uc73c\uba74 \ub78c\ub2e4 \uc2e4\ud589\n         * Run Lambda once copying is finished\n         *\n         * 4) \uc774\ubbf8 data_\uc5d0 \ub4e4\uc5b4\uc640 \uc788\ub294 \ubcc0\uc218\ub97c \ub78c\ub2e4\uc5d0\uc11c \uc0ac\uc6a9\n         * Using variables already in data_ in Lambda\n         *\/\n        socket_.async_read_some(boost::asio::buffer(data_),\n            &#91;this, self](boost::system::error_code ec, size_t len) {\n                if (!ec) {\n                    std::cout &lt;&lt; \"\ubc1b\uc74c\/Receive: \" &lt;&lt; std::string(data_, len) &lt;&lt; \"\\n\";\n                    do_write(len); \/\/ \uc5d0\ucf54 \/ echo\n                }\n            });\n    }\n\n    void do_write(size_t len) {\n        auto self = shared_from_this();\n        boost::asio::async_write(socket_, boost::asio::buffer(data_, len),\n            &#91;this, self](boost::system::error_code ec, size_t) {\n                if (!ec) do_read(); \/\/ \uc77d\uae30 \/ read\n            });\n    }\n};\n\n\/\/ --\nclass Server {\n    \/\/ socket() + bind() + listen()\uc218\ud589 \/ Execute socket() + bind() + listen()\n    tcp::acceptor acceptor_; \/\/ private\npublic:\n    Server(boost::asio::io_context&amp; io, short port)\n        : acceptor_(io, tcp::endpoint(tcp::v4(), port)) {\n        do_accept();\n    }\n\nprivate:\n    void do_accept() {\n        acceptor_.async_accept(\n            \/\/ \ub78c\ub2e4\ud568\uc218 \/ Lambda function\n            &#91;this](boost::system::error_code ec, tcp::socket socket) {\n                if (!ec) {\n                    \/\/ \uc5d0\ub7ec\uac00 \uc5c6\uc73c\uba74 \uc18c\ucf13\uc744 \uc138\uc158\uc5d0 \ub118\uae30\uace0 start \ud638\ucd9c, \uc18c\ucf13\uc740 \ubcf5\uc0ac \uc548\ub428\n                    \/\/ If there are no errors, pass the socket to the session and call start;\n                    \/\/ the socket is not copied\n                    std::make_shared&lt;Session&gt;(std::move(socket))-&gt;start();\n                }\n                \/\/ \ub2e4\uc74c \ud074\ub77c\uc774\uc5b8\ud2b8 \uacc4\uc18d \ubc1b\uc74c\n                \/\/ Continue accepting next client\n                \/\/\n                \/\/ \ubb34\ud55c\ub8e8\ud504 \/ infinite loop\n                do_accept();\n            });\n    }\n};\n\nint main() {\n    try {\n        boost::asio::io_context io;\n        Server s(io, 12345);\n        std::cout &lt;&lt; \"\uc11c\ubc84 \uc2dc\uc791. \ud3ec\ud2b8 12345 \/ Start server. Port 12345\\n\";\n        io.run();\n    } catch (std::exception&amp; e) {\n        std::cerr &lt;&lt; \"\uc5d0\ub7ec\/Error: \" &lt;&lt; e.what() &lt;&lt; \"\\n\";\n    }\n    return 0;\n}\n<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb\ucef4\ud30c\uc77c \/ Compiling<\/p>\n\n\n\n<p>&#8212; boot\ub77c\uc774\ube0c\ub7ec\ub9ac\uc758 \uacbd\ub85c\ub97c \ud3ec\ud568\ud569\ub2c8\ub2e4.<br>Includes the path to the boot library.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>g++ tcpecho.cpp -o server -std=c++17 -pthread \\\n  -I\/opt\/homebrew\/include \\\n  -L\/opt\/homebrew\/lib \\\n  -lboost_system<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb\uc2e4\ud589 \/ Run<\/p>\n\n\n\n<p>\u2714\ufe0f \ud130\ubbf8\ub110\uc744 \ub450\uac1c \uc5f4\uc5b4\uc11c \ud558\ub098\ub294 \uc11c\ubc84 \ud558\ub098\ub294 \ud074\ub77c\uc774\uc5b8\ud2b8\ub97c \uc2e4\ud589\ud569\ub2c8\ub2e4.<br>Open two terminals and run the server and the client in one.<\/p>\n\n\n\n<p>\u2714\ufe0fnc(netcat)\ub294 TCP\/UDP \ud1b5\uc2e0 \ud14c\uc2a4\ud2b8 \ub3c4\uad6c\uc785\ub2c8\ub2e4.<br>nc(netcat) is a TCP\/UDP communication test tool.<\/p>\n\n\n\n<p>\u2714\ufe0f \ud074\ub77c\uc774\uc5b8\ud2b8\ub294 nc localhost 12345\ub97c \uc2e4\ud589\ud569\ub2c8\ub2e4.<br>The client runs nc localhost 12345.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># server\n.\/server\n\n# client\n nc localhost 12345<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb\uc2e4\ud589 \uacb0\uacfc \/ Execution result<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"606\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/05\/terminal-jpg-1-1024x606.jpg\" alt=\"\" class=\"wp-image-5715\" srcset=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/05\/terminal-jpg-1-1024x606.jpg 1024w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/05\/terminal-jpg-1-300x178.jpg 300w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/05\/terminal-jpg-1-768x454.jpg 768w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/05\/terminal-jpg-1-400x237.jpg 400w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/05\/terminal-jpg-1-800x473.jpg 800w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/05\/terminal-jpg-1.jpg 1058w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">server\/nc<\/figcaption><\/figure>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\ud83d\udc49\ud83c\udffb c++\uc758 Asio(\ub610\ub294 Bootst.asio) \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uc774\ud574\ud558\uae30 \uc704\ud55c \ucf54\ub4dc\uc785\ub2c8\ub2e4.This is code to understand the C++ Asio (or Bootst.asio) library. \ud83d\udc49\ud83c\udffb \uc544\ub798\uc758 \ucf54\ub4dc\ub294 \uc774\uc804\uc5d0 \uc5c5\ub85c\ub4dc\ud55c mini_mediaserver_1 \uc758 \uc77c\ubd80\ub85c\uc9c1\uc744 \uc0ac\uc6a9\ud569\ub2c8\ub2e4.The code below uses some of the logic from the previously uploaded mini_mediaserver_1. \ud83d\udc49\ud83c\udffb \ud14c\uc2a4\ud2b8 \ud658\uacbd\uc740 MacOS\uc785\ub2c8\ub2e4.The test environment is MacOS. \ud83d\udc49\ud83c\udffb mini_mediaserver_1\uc740 standalone\ubc29\uc2dd\uc758 asio\ub97c \uc0ac\uc6a9\ud569\ub2c8\ub2e4.mini_mediaserver_1 uses standalone asio. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[23,1],"tags":[],"class_list":["post-5710","post","type-post","status-publish","format-standard","hentry","category-cpp","category-uncategorized","missing-thumbnail"],"_links":{"self":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/5710","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=5710"}],"version-history":[{"count":6,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/5710\/revisions"}],"predecessor-version":[{"id":5718,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/5710\/revisions\/5718"}],"wp:attachment":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=5710"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=5710"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=5710"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}