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

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

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

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

![gihyo00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/8d340724-ace0-06e3-43f5-425a95e0548c.png)

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

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

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

## 参考にした記事

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

- [Rustのお勉強 - Dockerで環境構築](https://qiita.com/toully/items/1b652bec2048eefd3130)

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

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

![gihyo01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/ae683517-9450-0975-13ca-ffb550dcd1dd.png)


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

![gihyo02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/5401b0fc-5720-5bbb-e5ea-80729b734d06.png)

## Dcoker Desktopをインストールする

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

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

[Docker Desktopダウンロードサイト](https://www.docker.com/products/docker-desktop)

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

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

### イメージをプルする

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

「rust docker」で検索し、[docker hub](https://hub.docker.com/_/rust)に行きます。
`docker pull rust`をせよ、と書いてあるので従います。

![rust-dockerhub.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/367e08e5-eb12-1d53-7576-efbb5174f149.png)

``` PowerShell
# 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`します。

``` PowerShell
> 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.rs`と`Cargo.toml`をサンプルコードの中身で置き換えます。
Cドライブ直下につくった`workspace`フォルダーの中にある`main.rs`ファイル2つと、`Cargo.toml`ファイルを書き換えます。

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

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

## いざ、通信させてみる

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

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

![docker-cli.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/f79bb45e-713f-5b26-fb43-2b844690e883.png)


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

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

![cli-connection.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/cd6d1c9c-6319-0f5f-d612-15e77f30cdcd.png)


## つづきは本書で

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

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