この文書は、著者が製作した network データ収集用C++ class library の設計方針について 述べたものである。
TCP stream や Thread を扱う C++ class library は世の中に既にある。そこで、 本パッケージでは特に凝ったことはしない。できるだけ単純に C の socket library や thread library を class 化するにとどめる。
一方 class 化するに当たり、model としたのは 、(実行効率はともかく)programming しやすい と言われている Java である。特に"JAVAプログラム クイック リファレンス"に掲載されて いる network の例題がほぼそのまま焼き直せることを強く意識した。
上記二つの要求を満たすために
Socket class に関しては、socket descriptor を隠蔽することを目的とする。従って、用意される member 関数は原則として、BSD socket library の socket descriptor を除いたものとする。
Socket descriptor は BSD socket library の socket() 関数を使って生成するが、 BSD socket library にはもう一つ socket descriptor を生成する accept() 関数がある。 これは stream 型で listen している socket から生成される。これをどう反映させるかが class 設計に大きく影響する。大雑把に次の二つの方法が考えられる。
前のページに述べたように、本class は標準libraryのiostreamに 近づけることを指針とする。iostreamから派生させることもできているが、現時点の配布パッケージには 含まれていない。従って、現時点ではmanipulatorの入出力先としては指定できない。
Socket の生成法の違いにより
入力に関して std::istream class との対応を以下の表に示す。
member function | implemented |
streamsize gcount() const | yes |
int get() | yes |
istream& get(char& c) | no |
istream& get(char* s, streamsize n) | no |
istream& get(char* s, streamsize n, char delim) | no |
istream& getline(char* s, streamsize n) | yes |
istream& getline(char* s, streamsize n, char delim) | no |
istream& ignore(streamsize n=1, int delim=traits::eof()) | delim 無しで実装 |
int peek() | no |
istream& read(char* s, streamsize n) | yes |
int readsome(char* s, streamsize n) | no |
istream& putback(char c) | no |
istream& unget() | no |
int sync() | yes |
出力に関しては std::ostream class との対応は以下の通り。
member function | implemented |
ostream& put(char c) | yes |
ostream& write(const char* s, streamsize n) | yes |
ostream& flush() | yes |
Thread class に関しては、start routine と thread desciptor を隠蔽する。 start routine を隠蔽する理由は、一般に start routine は global object であり、thread で操作したい data object との結びつきをユーザが設定しなければならないために、 ユーザにとって必ずしも使いやすくないからである。
C++ はデータとその操作関数を一体的に 記述できることが利点の一つであるので、これを一体的に扱える設計にした。 この model として Java の runnable class 的に使える設計にした。
ユーザは基本的に Thread として実行したい関数及びその時に必要となる data をひとまとめにして Thread class から派生させた class をつくり、
Thread 間での排他制御や同期をとるために、Mutex と Semaphore の 二つの class を用意した。これらはいずれも POSIX の mutex と semaphore に対応 させてある。