ネットワークプログラミングをしてみたい


Software Designネットワークプログラミング

twitterでSoftware Design3月号が話題になっていた。
オブジェクト指向の特集だった。

そのオブジェクト指向特集とは別で、Rustをつかったネットワークプログラミングの記事があった。
この記事を書いているのは「電気ひつじ (teru0x1) · Twitter」様です。
電子書籍も出版されているようで、つまりは神クラスの御仁です。

登大遊氏がメディアに多く出演していて、ネットワークプログラミングのスバラシさについて説いているのを見ると
ネットワークプログラミングの触りくらいは体験してみたくなる。

というわけで、この記事ではSoftware Designのネットワークプログラミングの記事をなぞらえてみることをします。
ネットワークプログラミングの記事は連載記事であり、1月号から始まったらしい。

※私の使っているPCはWindows 10です。

参考にした記事

いつもお世話になっております。

Software Design1月号のサンプルコードをダウンロードする

サンプルコードをダウンロードする権利は、雑誌を購入した人にしかないのだろうか。
おもむろに技術評論社のサポートページで「ネットワークプログラミグ」を検索してみる。

検索結果の一覧に2021年1月号のリンクが出現するので、おもむろにクリックする。
その先にサンプルコードのダウンロードリンクのようなものがあったような、なかったような・・・。

Dcoker Desktopをインストールする

ネットワークプログラミングはRustを使って実行する。
新しいプログラミング環境をさくっと実行するには、Dockerという技術が便利らしい。

まずはDockerの環境をつくる。

Docker Desktopダウンロードサイト

ダウンロードしたら動作確認をかねてバージョンを表示する。
以後、Rustの操作も含めすべてPowerShell上で完結する。

> docker --version
Docker version 20.10.2, build 2291f61

イメージをプルする

Dockerが何者かよくわかっていませんが・・・
Google検索の上位のリンクをたどっていけば、わからなくてもなんとかなるものです。

「rust docker」で検索し、docker hubに行きます。
docker pull rustをせよ、と書いてあるので従います。

# docker pull rustする前
# イメージが何もない。
> docker images
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE

# イメージをプルする
# 完了するまでに3分くらいかかりました
> docker pull rust
Using default tag: latest
latest: Pulling from library/rust
8bf9c589d5f9: Pull complete
4c70e46d8b5f: Pull complete
ea848ad42f0d: Pull complete
48fe137f8d26: Pull complete
4b13f6ed9b0c: Pull complete
8a08deff2c33: Pull complete
Digest: sha256:e57a7b85bcbabb5bebbbd8e900e21fbdd014408347c37fc789485469f6bd7595
Status: Downloaded newer image for rust:latest
docker.io/library/rust:latest

# docker pull rustした後
# イメージ一覧にrustが追加されました
> docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
rust         latest    68fa8c8b027f   20 hours ago   1.25GB

Dockerコンテナーの中でRustを体験する

コンテナーの意味もよくわかりませんが、中に入れるそうです。

Cドライブ直下にworkspaceフォルダーを作成しておきます。
コンテナーの中のあちら側の世界と、ふだんエクスプローラーで開いているこちら側の世界を行き来するためのフォルダーです。
あちら側とこちら側の共有フォルダーであると認識しています。

あちら側とこちら側で思い出しましたが。シャーマンキングが4月から放送されるようです。懐かしいです。

コンテナーの中に入る

参考サイトによると、書きコマンドを打つとコンテナーに入れるようです。
docker run -itv /C/workspace:/workspace --name rust-env rust

名前がrust-envというrustイメージのコンテナーをrunしているようです。
runするだけで中に入れるのか、-itvあたりの何かが入らせてくれているのか、不明です。あとで勉強します。

あちら側の世界で作業をする

あちら側(コンテナーの中)で作業ディレクトリに移動し、そこでさらに新しいフォルダーをnewします。

> cd workspace
# この時点でworkspace内はからっぽ

> cargo new echo-server
> cargo new echo-client
# workspace内にふたつのフォルダーが生成されています
# >/workspace# ls
# echo-client  echo-server

cargo newの操作をすると「Created binary (application) echo-server package」という文字列とともに、新しいフォルダーが生成されます。

さらにそのフォルダーの中にsrcフォルダーとCargo.tomlファイルがあります。
srcの中にはmain.rsが入っています。

デフォルトのmain.rsの中身
rust
fn main() {
println!("Hello, world!");
}

こちら側の世界で作業をする

自動生成されたmain.rsCargo.tomlをサンプルコードの中身で置き換えます。
Cドライブ直下につくったworkspaceフォルダーの中にあるmain.rsファイル2つと、Cargo.tomlファイルを書き換えます。

コンテナーの中でcat echo-client/src/main.rsを打って、main.rsの中身が書き変わったことを確認します。

(結果はここには書きません。なにか悪いことのような気がするので・・・)

いざ、通信させてみる

サーバーとクライアントの両方をつかうので、プロセスがふたつ必要です。
プロセスをふたつ・・・?
よくわかりませんが、面倒なのでDocker Desktopさんの力を借ります

CLIを2回クリックして窓をふたつ用意します。
片方がサーバー役、もう片方がクライアント役です。

先にサーバー役の窓(左)でcargo runをしてサーバーを起動します。
次にクライアント役の窓(右)で同じくcargo run、つづけてHelloを打ちエンター、つづけてWorldを打ちエンターしました。

結果、左のサーバーへメッセージが2回分けて届いたことがわかります。
また、クライアント側にもサーバーへ送ったメッセージがそのまま返された結果、同じ文字列が2重で表示されています(上は自分の送信、下はサーバーからの受信)

つづきは本書で

本書ではこの先で、意図的にパケットロスを引き起こしたときの挙動をWiresharkを使って監視したりします。

残念ながらdockerコンテナーの中でグラフィカルなWiresharkを動かく術を知らないので
この記事はここまでです。