ときどき 、
bashにささいなことを書くのが好きです。 私がすでに「Habr」で
話したネットワークチェスのように。
最近、私は精神的に彼らに戻り、ゲーム自体がオンラインでプレイするためのパートナーを見つけることができたらどんなに素晴らしいだろうと考えました。 つまり おもちゃが発売されると、どうにかしてネットワークを検索して、戦いの準備ができている人を探します。
一般に、すべてのアドレスをスキャンすることは長時間不可能です。 2つのtwoい「正面」ソリューションがあります-現在のサブネットをスキャンするか、
ARPテーブルを見て、そこにいる人に接続します。 しかし、第一に、このソートは依然として低速であり、第二に、潜在的なライバルをすべて見つけることができません(ライバルは他のサブネット上にあり、
ARPテーブル内のすべてのネットワーク参加者ではありません)。
一般に、OSで同様の問題がかなり前に解決されました。たとえば、自宅でネットワークプリンターをセットアップしたとき、オペレーティングシステムが自分で見つけたので、
IPなどを指定しませんでした。 このための「Mac」には、
Bonjourテクノロジー(
Zerokonfの実装)があります。
このテクノロジーをBashで使用することは可能ですか?
私はネットワークチェスを書き直さず、すべてを開始したという考えで、代わりに、次のアルゴリズムに従って動作するファイル転送ユーティリティを作成しようとしました:2台のマシンで実行され、コンピュータがお互いを見るとどのファイルを転送する必要があるかを示しますネットワーク、次にファイルが転送されます。 これらはすべて
、これらのマシンの
IPまたは名前を指定せずに実行します。
Macには
dns-sdユーティリティ(または
mDNSの古いバージョン)があり、ネットワークサービスとその発見の発表に従事しています。 つまり いくつかのキーで開始され、彼女は「このコンピューターはこれを行うことができます」と言います。
方法は次のとおりです。
サービスは名前で指定され、サービス名はUnicode文字列(
UTF-8形式)、最大63バイト(文字ではない)、 "
_app-proto._tcp "または "
_app-proto._udp "の形式で設定されます。サービスの名前です)「
app-proto 」は特別なサイトに登録する必要がありますが、ユーティリティは任意の値を取るため、このステップは不要です。
一般に、キー「-R」を指定して
dns-sdを実行すると、ネットワークに新しいサービスが登録されます。
「-B」キーを使用して同じコマンドを実行することにより、ネットワーク上で検索できます。
ご覧のように、サービス名に加えて、他のパラメーターがありますが、実際には「Hello!」行に加えて、興味深いものは何もありません。これらはこの実装には影響しません。 この行の「こんにちは」の代わりに、もっと便利なものを書くことができます。 サービスと転送されたファイルのチェックサムを発表した
IPマシンに関する情報を書き留めます。
コードのビット。
これは私のコードではサーバーのアナウンスがどのように見えるかです:
ご覧のとおり、バックグラウンドでサービスのアナウンスを開始し、ユーティリティの終了時にバックグラウンドで実行されている
dns-sdを打ちました。 バックグラウンドで起動を使用しない場合、スクリプトの実行はその場所で停止します-起動後の
dns-sdは制御を返さず、終了すると、発表されたものからサービスを削除します。
今、サービスの発見。 このモードでは、
dns-sdは
トップユーティリティに似ています-コンソールもリリースされず、アナウンスおよびアナウンス解除されたサービスに関するイベントが画面に表示されます。 したがって、
expectユーティリティを使用する必要がありました。これは、このような場合に非常に便利です。
local info=($(expect <<CMDS | awk 'NR>2 {print $7 " " $8}' | sort -u | tr -d '\r' | head -n1 spawn -noecho dns-sd -B _bolk-fileshare._tcp expect Timestamp expect -- "_bolk-fileshare._tcp" exit CMDS))
ここでの意味は次のとおりです
。dns-sdにサービスの名前の行が表示されたら、制御を返すことを
期待します。 その後、必要なものを選択します。サーバーの
IPアドレスと送信されたファイルのチェックサムが転送されるまさにその行です。
info変数では、合計と
IPという2つの要素の配列を取得し
ます 。
残りはあまりおもしろくありません。結果のコード
は GitHubに
あります。指定されたアドレスに接続し、
netcatユーティリティでファイルを取得します。
要約すると、アイデアは次のとおりです。対戦相手を検索するネットワークゲームは、特定の名前のサービスをアナウンスし、同時にアナウンスされたサービスをスキャンして、プレイしたいプレイヤーに尋ねます。 プレイヤーが誰かを選択すると、マシンが指定されたアドレスに接続され、ゲームが開始されます。