LoginSignup
6
1

More than 1 year has passed since last update.

Go言語でpingコマンドっぽい、でもpingコマンドじゃないpongコマンドを作ってみた

Last updated at Posted at 2022-11-30

はじめに

  • Go 言語で pong コマンドを作成しました
  • POng is Not pinG :「pong コマンドは ping コマンドではありません」
  • 本コマンドは kurehajime 様の作った「 Go言語でpongコマンドを実装する 」に多大な影響を受けております

pong コマンドとは?

まずは、以下の画像をご覧ください(下記 Qiita の記事より借用しております)。

注:この画像・コマンドは私の作ったものではありません。

pong.gif

あるいは以下の記事、もしくはリポジトリをご覧ください。

これは kurehajime 様の作った pong コマンドです。

非常に素晴らしいアイデアではないでしょうか。

pongping のキータイプは近いですし(QWERTY配列だと、OI は隣り合っている)、ls コマンドに対する sl コマンドのキータイプ矯正効果に近いものを感じます。

上記の記事やコマンドのアイデアが素晴らしいと感じた方は、以降の本文を読む前に上記記事に「いいね」を、あるいはリポジトリにスターをしてくるとよいのではないかと思います。

ところで、私はこのコマンドを見たときに、「素晴らしいアイデアだ」と思うと同時に「別の方向性(可能性)もあるのでは?」と思いました。

そこで、まず pong ゲームと、ping コマンドについて整理します。

pong ゲームとは?

いわゆる卓球(ping pong; ピンポン)のようなゲームです。有史以来、さまざまな pong ゲームが作られてきました。

二人で対戦、あるいはユーザ対コンピュータでの対戦をするのが一般的です。
画面の左右(あるいは上下)に、パドル(ラケット)があり、お互いにパドルを操作してボールを打ち合います。

おそらく e スポーツのはしりといっても過言ではないと思います1

ping コマンドとは?

ping コマンドは、IP ネットワークにおいて、ネットワーク上の特定の IP アドレスを持つ機器からの応答があるかを調べるコマンドです。

通常、ping コマンドはターゲットホスト(IP アドレス、あるいはホスト名)を指定して、実行されます。

実行された ping コマンドは、ICMP プロトコルの echo request パケットをターゲットに向けて送信します。
ターゲットホストは、ICMP の echo request パケットを受け取ると、送信元に対して echo reply パケットを返します(設定などにより返さないホストも存在します)。

ターゲットホストが同一ネットワークにない場合には、ネットワーク同士をつなぐ Gateway が echo request/reply パケットをリレーします。その際、パケットにある TTL (Time To Live) の値を 1 だけ減らし、もし減らした結果が 0 の場合にはパケットをリレーせず、破棄します。

ping コマンドは、ターゲットホストから ICMP の echo reply が返ってくること、あるいは返ってこないことで、ネットワーク到達性、応答時間などを記録します。

実行環境(ping コマンドの種類)によって異なりますが、規定の回数、あるいはユーザの停止操作(例: CTRL+C など)がされるまで ICMP の echo パケットを送受信して、最後にその結果をレポートします。

ぼくのかんがえたさいきょうの pong コマンド

そこで、私の考えた pong コマンドは以下のようになりました。

yet-another-pong.gif

ターゲットホストを指定して pong コマンドを実行すると、ローカルホスト(画面の左端にあります)は、ICMP ECHO パケットを送信します。

ターゲットホスト(右側にあるあなたが操作するパドル)で、送信されてくる ICMP ECHO パケットを受け止めて、送信元のホスト(左端のローカルホスト)に送り返してください。

しかし、その間にある Gateway (画面左側のパドル。コンピューターが操作する)は、何を間違えたのか、ICMP ECHO パケットを受信すると、必ずターゲットホスト側に送り返してしまいます。
そこであなたは、Gateway をさけつつ、ICMP ECHO パケットをローカルホストに送り返す必要があります。
Gateway が送り返す際には TTL が減るので、TTL がなくなる前に送り返してください(デフォルトでは TTL は 64 からスタートします)。

また、何度も送り返していると、徐々にネットワークスピードが上がっていきます。注意してください。

デフォルトでは、ローカルホストは ICMP ECHO パケットを 4 回送信します。
最後のパケットを受信(あるいはロスト)した後、あるいはユーザが停止操作をした場合には、それまでのパケット応答状態の統計情報を表示します。

本 pong コマンドの起動方法は以下のようになります。

pong [options] <destination>

また、オプションとして以下のものが指定可能です。

Application Options:
  -h, --help                 print help and exit
  -v, --version              print version and exit
  -c, --count=<count>        stop after <count> replies (default: 4)
  -t, --ttl=<ttl>            define time to live (default: 64)
  -p, --padding=<pattern>    contents of padding byte

Arguments:
  <destination>:             dns name or ip address

ソースは以下のリポジトリに置いてあります。

kurehajime 様の作った pong コマンド同様に、Go 言語で実装しています。

画面操作ライブラリは、最初 termbox-go を使用していましたが、作者が「もうこのライブラリはメンテナンスしていないから、たとえば gdamore/tcell などをつかったらいいんじゃない」というので、gdamore/tcell を使うようにしてみました。と言っても termbox-go 互換機能があるのでそれを使っているだけですが。

注:章タイトルに含まれる「さいきょうの」には意味がありません。なんとなく書いてみただけです。「ぼくのかんがえた pong コマンド」と同じ意味です。

  1. 多分、過言です

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1