主なコンテンツ

〜主なコンテンツ〜

1. Unityで製作したゲームと製作Tips
  1. 三月精チャレンジ(東方Project二次創作)
    1. 作り方
  2. 英語学習2D(オリジナルスマホアプリ)
2. UE4
3. ゲームアプリ見学
4. Bitbucket & SourceTreeでの一連の流れ
  1. 前半
  2. 後半
5. Tips
  1. UnityのTips
  5. SQL文のTips
  6. Final IK
  7. GearVR+Unity

2016年3月19日土曜日

書籍「オンラインゲームのしくみ Unityで覚えるネットワークプログラミング」の解読


表題の書籍は、PhotonやUnityMultiPlayerでの同期が幅を利かせている中、ソケットプログラミングで同期をするという硬派なもの。2014年初版なので少々古いためかもしれない。優しげな外見と中身に反して、サンプルコードを用意していることを伝え忘れたまま、どこでどう定義されたのか分からないクラス・メンバをどんどん使い始める魔本。Unityやゲーム業界の変革が早すぎるため、色々と手が回らずに出版される書籍がけっこう多い。

立ち読みの時点で、ソケット通信APIの具体的な使用方法の説明が一切無いなど気になる部分があったが、面白そうなので調べながら読み進めてみることにした。私は完全に素人なので「バッファ」って何?というレベルからスタートする。流し読みした限りでは、ソケット通信=P2Pという印象を受けている。この印象が正しいかどうかはいずれ分かるということで。それにしても現状技術書は内容を立ち読みで確認しないと怖くて買えないので、大型書店のない田舎人には辛い状況。

〜その他〜

  • サポートページ
    • 実はここにソースコードがある(何処で説明があった…?)
    • Unity5用のコードは解凍すると1.2GB程になる
    • キャラクターは商用利用OK、再配布不可
  • バンナムフェア
    • 書籍購入特典があるが、別にパスワード等は無いので誰でもDLできる
  •  現時点での感想('16.03.21)
    • サンプルを試してみたがエラーが出る パソコン2台でサンプルを起動させ、正常に動作することを確認した(詳しくはこの記事の後半に記載)

〜以下、初心者目線での書籍の補完


■用語

第2章
  • バッファ:
    • 処理する速さの異なる端末間でデータのやり取りをする際、一時的にデータを溜めておくためのメモリ領域(参考
  • 受信バッファ:
    • 受信側のバッファ
  • バッファサイズ:
    • おそらく別名ウィンドウサイズと呼ばれているもののこと。バッファが保存できるデータの量。
  • バッファオーバーフロー:
    • ウィンドウサイズより大きなデータが来ること。溢れたデータはロストしてしまう。TCPは送信データのサイズと受信バッファのサイズを比較して、問題ないことを確認してから送信する。
第3章
  • イーサネット
    • LANの代表的な接続方式。ちなみにイーサはetherと記載し、古典物理の光の仮想物質「エーテル」から来ている(参考:wikipadia)。
  • イーサネットポート
    • 端的に言えばLANの差込口のこと
  • エンドポイント
    • ネットワーク接続の末端にあるデバイスのこと(参考
  • ローカルエンドポイント
    • おそらくエンドポイントのうち、自分側のデバイスのこと。対義語はリモートエンドポイント(参考)。
  • ドメイン
    • インターネット上にあるコンピューターを特定するために、特定のルールに基づいて作られた文字列のこと(参考
  • イントラネット
    • インターネット標準技術に基づく企業内ネットワーク(参考
  • インターネット標準技術
    • SMTP、POPなどを用いたメールシステム
    • HTTPを用いた情報閲覧システム
    • NNTPを用いたニュースシステム
  • DNS(重要!!)
    • ドメインネームシステムの略(参考
      • ホスト名を元にIPアドレスを調べる
      • 他のパソコンとIPアドレスが被らないよう、ネットワーク接続されたパソコンのIPアドレスを登録して管理する
      • 参考先から抜粋
        • JPNIC Web(http://www.nic.ad.jp/)をWebブラウザで見る場合、実際にはwww.nic.ad.jpのIPアドレスである202.12.30.144という宛先IPアドレスに対して通信が行われることになります。そのためhttp://www.nic.ad.jp/を指定するかわりにhttp://202.12.30.144/とすることも可能です
        • しかし、このようにIPアドレスで相手先を直接指定することは、Webサーバ等のIPアドレスをなんらかの方法ですべて記憶しておく必要があり、現実的ではありません。
        • そのため、より人間が覚えやすく使いやすい「名前(例:www.nic.ad.jp)」で指定できるようにするためのしくみが必要となります。DNSはそれを実現するためのシステムです。

■C#でのソケット通信

第3章
TCPサーバーの待ち受け
  • 名前空間で必要となるもの(参考
  • 実際に使用されていたもの(要サンプルコード確認)
  • System.Net.Sockets
  • System.Net
  • StartListener(int port)としているが、サンプルでは引数を取ることを止め、m_portという定数のメンバを用いている。以降のページでも、このm_portが用いられている。このポート番号は50765で固定(何でこの番号なのか不明)。
  • Stateは自作の列挙体で、主にUpdateで処理の分岐に使われている


  • p39のコードにあるm_isConnectedはサンプルに存在しない使わなくなったメンバ。接続状況はBool代数ではなく、前述のState列挙体を用いている。
TCPクライアントの接続
  • System.Net.Sockets
    • Socketクラス
      • Socket.NoDelayプロパティ
        • Socket が Nagle アルゴリズムを使用するかどうかを設定・所得できる
        • 使用する場合はfalse。それ以外の場合はtrue。既定値はfalse
        •  Nagle アルゴリズムとは小さなパケットをバッファリングして(溜め込んで)から送信する仕組み。これにより、細切れの通信が回線を圧迫することで生じる遅延や損失、再送信となるリスクを抑える。
      • Socket.SendBufferSizeプロパティ
        • 送信時に一時的保管するデータの大きさ。これを0にすると、おそらく相手の状況に関わらずデータを溜め込むことなく送信し続ける。
      • Socket.Connectメソッド
        • 指定されたリモートホストへの接続を確立する。IPアドレスとポートでホストを指定する以外にも、色々な引数が使用可能(要リファレンス確認)。
      • Socket.Send メソッド (Byte[], Int32, SocketFlags)
        • 送信データは基本的にByte型の配列
        • 引数の取り方は様々。書籍ではバイト数とフラグを指定して送信しているが、今回の例ではここまで指定する必要は無いように思える。
        • プロバイダーの最大パケットサイズを越えると、送信されずエラーを返す
        • 受信相手がデータを保存するのに十分なバッファーを持たない場合は、ブロッキングモードを解除していない限り、送信はブロックされる
      • SocketFlags列挙体
        • ソケットの送受信動作を指定する
      • Socket.Receive メソッド (Byte[], Int32, SocketFlags)
        • 戻り値はInt型
        • Send関数同様、引数の取り方は様々
      • Shutdown メソッド
        • ソケットでの送受信を無効にする
        • おそらく送受信を無効にした上で、現在ソケットのバッファにある送受信は全て実行される
      • SocketShutdown 列挙体
        • Both:送信と受信の両方を無効にする
        • Receive:受信を無効にする
        • Send:送信を無効にする
      • Closeメソッド
        • ソケット接続を閉じ、関連するリソースを全て解放する
        • 送信側、受信側それぞれで呼び出す必要がある
  • 「Byte型→文字列」への変換と、「文字列→Byte型」への変換について(参考
    • Byte型→文字列
      • System.Text.Encoding.UTF8.GetString(bytesData)
    • 文字列→Byte型
      • System.Text.Encoding.UTF8.GetBytes(str);

■動作チェック

実際に通信できているか確認するためには、通信相手のIPアドレスが必要となる。よって2台のデバイスで作成したプログラムを起動する必要がある(多分、スタンドアロンアプリとしてビルドすれば、同一パソコン内でUnityとアプリ間で通信させることも可能だと思う)。

ここでは第4章のサンプルで確認を行った。サンプルを再生するとIPアドレス入力画面が表示される。ここで表示されている文字列はhostAddress.ToString()によるもの。表示されているIPアドレスを互いに入力し合うとちゃんと通信ができた。



  • System.Net
    • IPHostEntryクラス
      • ホストのIPアドレス情報コンテナークラスを提供する
      • DNS(ドメインネームシステム)クラスのヘルパークラスとして使用される
      • AddressList プロパティ
        • ホストと関連付けられたIPアドレスのリストを取得・設定する
      • HostName プロパティ
        • サーバーのプライマリホスト名を取得・設定する
    • Dnsクラス
      • インターネットのDNSから特定のホストについての情報を取得する静的クラス
      • GetHostEntry メソッド (String)
        • ホスト名と関連付けられたIPアドレスを照会する
        • ホスト名に関連するすべての IP アドレス候補が取得され、AddressList プロパティとして設定される
      • GetHostName メソッド ()
        • ローカルコンピューターのDNSホスト名を取得する


〜参考〜

0 件のコメント:

コメントを投稿