メモ: ZeroMQの入り口
通信の基本的な意味で*ZeroMQ(v4)* を勉強した。
資料
下に目を通せば大丈夫そうな気配がある。
- ØMQ Community
- Learn the Basics
- ZeroMQ Feature List
- ØMQ - The Guide
- ØMQ - The Guide(日本語訳-4章まで/8章)
- API Reference
- ZeroMQ RFC
通信状況を解析する
通信内容を解析したい
wiresharkで解析するDissectorを書いてる人がいたので利用する。
通信量を追いたい
トラフィック量だけでいいのであればやってみた的な記事がコミュニティ配下にあったので参考にする。
リーディング
ZeroMQ のトランスポートプロトコル (QUIC,PCC,SCTP, …)を追加したくなったと仮定してコードを読んだ。
TL;DR
手始めにzmq_bind を起点にTCPに重点を置いてコードを追った。 bindを成功させるには下をすれば良いと思われる所までは読めた(はず)。
- プロトコルに対応付けるオブジェクトをown_t を継承して作成する
- zmq::socket_base_t::check_protocol, zmq::socket_base_t::bind を変更しプロトコルを許可する
- zmq::socket_base_t::bind の追加したコードでzmq::socket_base_t::add_endpoint を呼び出す
続けてconnect, recv, send系を読んで条件を確認すればZeroMQのトランスポートレイヤ追加も夢じゃない!(はず..) recvくらいは読むかもだけど本格的に追うかは迷い。 あとIPv6周辺のコードが未だに苦手だと感じたので勉強しておきたい。
リーディングメモ
追いやすいところからコードは入ると良い。 API Referenceで公開されているAPIを確認する。 ØMQ - The Guideで使い方の流れを押さえておく。
流れは下な感じになる。
- contextを作り
- socketを作り
- bindしたりconnectする
- recvしたりsendしたりする
zmq_bind関数を追う
Cではzmq_bind 関数によりソケットをトランスポートプロトコルと紐付ける。
include/zmq.h
|
|
具体的には以下のようになっている。void * として受け取ったソケットを検査しbind メソッドを呼び出している。
バインドにはアドレスとして(char *addr_
)が入る。
|
|
s->bind
のコード箇所はsrc/socket_base.cpp にある。
socket_base_t::bind についてtcp に注目して大枠を確認する。 ZeroMQ のソケットは配下に多くのプロトコルやエンドポイントを保持して1つとして扱えるためadd_endpoint() によりエンドポイント毎に管理していると想像した。
- 上位レイヤから渡されたアドレス*(addr_*)をaddressに格納する
- listner->set_address() の中、下位のTCPソケットを準備(open_socket() からlisten() まで)して*# lisner->s* で保持する
- add_endpoint() でリスナーをエンドポイントをキーにsocket_base_t のソケットに接続する
|
|
add_endpoint を確認するとlaunch_chid でソケットとリスナーを繋いでendpoints.insert で管理情報を登録していた。
|
|
ちなみにset_address 内で確保されるTCPソケットは以下のようなオプションが設定されていてbindしたいアドレスがTIME_WAIT で残っていても大丈夫。
|
|