始めに
低レイヤーの事は他のページみてください
TCP/IP、バークレーソケット等を知らなくてもいい前提でなるべくかきます
毎週1記事、勉強した事をQiitaに書き留めるので
間違っている部分あれば マサカリお願いします!
環境
IDE
MacでCLionを使っています。ので CMakeです。
他のmakeでも動きますが、今のうちにCMakeに慣れておくと良いと思います
(私もCMakeは初めてです)
boost
現時点で最新のboost1.57.0 を使ってます。他のバージョンでもだいたい大丈夫と思います
Homebrewなりportsなりaptなりでインストールしてもいいと思います
私はソースからインストールしました
$ cd BOOSTのルート
$ ./bootstrap.sh
$ ./b2 install --prefix=ライブラリパス
で終わり。簡単です。
--prefixを省略すると /usr/local/lib 以下に作成されます
サーバー側ソース
#include <iostream>
#include <boost/asio.hpp>
using namespace std;
using namespace boost::asio ;
static const int PORT_NO = 8080;
int main() {
boost::asio::io_service io;
while(true) {
ip::tcp::iostream buf;
ip::tcp::acceptor accept( io, ip::tcp::endpoint(ip::tcp::v4(), PORT_NO ));
accept.accept(*buf.rdbuf());
std::string temp;
while (true) {
buf >> temp;
if (temp == "quit") {
buf << ">>bye" << std::endl;
break;
}
buf << ">>" << temp << std::endl;
}
}
return 0;
}
cmake_minimum_required(VERSION 2.8.4)
project(asio1)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/bin")
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_HOME_DIRECTORY}/bin")
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
include_directories(${Boost_INCLUDE_DIRS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
find_package(Boost 1.57.0 COMPONENTS system)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(asio1 ${SOURCE_FILES})
target_link_libraries(asio1 ${Boost_LIBRARIES})
endif()
localhostの PORT_NOポートに 文字列を送ると同じ文字列を返す
echoサービスです
"quit" を送るとクライアントは終了する
再び接続出来る
実行して telnetで動作確認してみます
miyatake_y$ telnet -4 localhost 8080
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
yahoo
>>yahoo
hoge
>>hoge
moge
>>moge
quit
>>bye
Connection closed by foreign host.
正常に動きましたね!
クライアントソースは省略します(telnetで確認できるので)
上記のプログラムは
最も基本的な(実践ではあまり使わない)シングルスレッドモデルです
試しに複数telnetから接続しても 2つ目以降は接続できません
これをマルチスレッドにすれば、非同期通信が出来ますが
リソースの問題、コンテキストスイッチの問題等のため
ReactorパターンやProactorパターンを使う事が多いです
次は Proactorパターンを実装してみたいと思います。