TCP/IP通信による同期描画

Last update: <2004/03/13 17:29:53 +0900>

TCP/IP通信

ネットワーク通信の基礎に関する話をいまさらここでしようとは思いませんが,最低限,この勉強会で身につけておく(思い出して欲しい)事柄について触れます.

コンピュータとコンピュータが互いにやりとりするためには,その手順を決めておかなければなりません.これをプロトコル(protocol)といいます.現在のコンピュータ通信において,もっとも普及しているのはTCP/IPです.IPというのはInternet Protocolの略で,コンピュータ間のデータ転送をおこなうためのプロトコルです.またTCPはTransport Control Protocolで,IPを利用しアプリケーション間のデータ転送をおこなうためのプロトコルです.

TCP/IPでは,コンピュータの識別子としてIPアドレスを使用します.ご存知の通り,IPアドレスとは'.'で区切られた4つの整数のことで,150.89.238.131というように表されます.IPアドレスは,TCP/IPでネットワーク接続されているコンピュータに固有に割り当てられています.*22

自分が今使っているマシンのIPアドレスを調べてみましょう.スタート=>プログラム=>コマンドプロンプトで, c:\>ipconfig と入力します.



さて,普段何気なく使用している電子メールやウェブなどですが,これらの通信はすべてTCP/IPにより実現されています.同じコンピュータで同時に電子メール,ウェブ,チャットなどをおこなうことができますが,これはIPアドレスの他にポート番号によって,処理内容に応じて切り替えて使っているからです.例えば電子メール(SMTP)はポート番号が25番,ウェブ(HTTP)は80番というようなルールになっています.

Unix系やWindowsNT系のマシンでは,ポート番号がどんなアプリケーションに割り当てられているか調べることができます.Unix系では/etc/services,WindowsNT系ではc:\winnt\system32\servicesにファイルがあります.lessやnotepadなどで開き,見てみましょう.


通信を利用したアプリケーションでは,サービスを提供する側のサーバと,サービスを受ける側のクライアントがあります.サーバは常に自分のポート番号を見張っていて,クライアントがサーバのIPとポート番号を指定してアクセスすると,通信が成立します.

アプリケーションで通信をするためには,ソケットという概念を用います.サーバ用のソケット,クライアントのソケットを両方のマシンで用意します.サーバ用のソケットにはポート番号がついており,クライアントの接続があるまで待ち続けます.クライアントがサーバのIPとポート番号を指定したソケットを作製し,指定されたIPのサーバに問い合わせます.ソケットとソケットが通い合えば通信が開始になります.


ネットワークプログラミングの基礎

さて,実際の通信プログラムではどのような手順で通信が確立するのでしょうか. 以下の表にまとめました.

サーバ側クライアント側
起動
ソケット作成(socket)
ポート番号の割り当て(bind)
接続待ち(listen)
|起動
|ソケット作成(socket)
|ポート番号,通信先の設定
接続受付け(accept)通信先に接続(connect)
接続完了


通信の接続が完了すると,あとはお互いにデータの読み書きをすることになります.サーバとクライアントでは,当然ですが送受信が対になります.

サーバ側クライアント側
接続完了
......
送信(send)受信(recv)
......
受信(recv)送信(send)
......


受信のコマンド(recv)は,データを受け取るまで待ちます.つまりデータが来なければ次の処理に進めません(blocking).データのやり取りを手順を間違えると,受信時にプログラムがフリーズすることも珍しくありません.フリーズを回避するには,データやりとりの手順をしっかり決めておくことが重要です.

接続を終了するには,クライアント側から切るのが流儀です.

サーバ側クライアント側

終了(close)
終了または接続待ち


クライアント,サーバの通信プログラムを作成してみましょう.

  1. サーバプログラム,クライアントプログラム用に,プロジェクト2個を用意します.プロジェクトの作成方法は第1回演習,管理方法は第4回演習を見て下さい.


  2. 今回はサーバとクライアント2つのプログラムを同時に開発しますので,ワークスペースの中に2つプロジェクトを置くと便利です.画面のようにワークスペースの部分で右クリックをして追加することができます.



  3. 通信ライブラリプログラム をダウンロードし,両方のプロジェクトに追加します.


  4. プロジェクト=>設定のリンクで,ライブラリモジュールにws2_32.libを追加します.両方のプロジェクトに設定が必要です.




  5. 次のプログラムを見て下さい. /* サーバサンプルプログラム */ #include <stdio.h> #include "socket.h" void main(void) { int netd, fd; unsigned char data; InitSocket(); /* ソケットの初期化 */ OpenServer(&netd, 60001); /* ソケット作成,設定 */ WaitServer(netd, &fd); /* 接続待ち */ /* 接続完了 */ while(1){ ReadSocket(fd,1,&data); /* データ受信 */ if(data=='q')break; /* 'q'キーが押されたら終了 */ printf("%c", data); /* 受信データの表示 */ WriteSocket(fd,1,&data);/* 同じデータを送信しなおす */ } /* 接続終了 */ CloseServer(fd); QuitServer(); }
    このプログラムはポート番号60001番を使用したサーバ側プログラムです.1バイト受信すると,その受信データを表示した後,同じデータを送り返すものです.'q'キーのアスキーコードがデータとして送られてくると,無限ループを抜け終了します.

    netdはソケット記述子,fdは現在接続されているソケットの記述子です.サーバはソケット記述子で待ち受けますが,現在接続されているソケットとは区別します.サーバが複数のクライアントを待ち受けることもあるからです.

    このプログラムをサーバ側のプロジェクトに追加してコンパイルします.ファイル名は何でも構いません.


  6. 次のプログラムを見て下さい. /* クライアントサンプルプログラム */ #include <stdio.h> #include <conio.h> #include "socket.h" void main(void) { int netd; unsigned char data=0; unsigned char recv_data; InitSocket(); /* ソケットの初期化 */ if(!OpenClient(&netd, 60001, "150.89.238.131")){ fprintf(stderr,"open error\n"); exit(1); } /* 接続完了 */ while(1){ data=getch(); WriteSocket(netd,1,&data);/* データ送信 */ if(data=='q')break; ReadSocket(netd,1,&recv_data); /* データ受信 */ printf("%c", recv_data); /* 受信データの表示 */ } CloseClient(netd); } このプログラムは,IPアドレスが"150.89.238.131",ポート番号60001番のサーバと接続するためのクライアントプログラムです.接続が完了した時点でキーボードを押すと,そのアスキーコードが1文字送信されます.また,サーバ側から受け取った1バイトのデータを表示しています.'q'キーを押すと接続を終了します.

    netdはソケット記述子です.

    このプログラムをクライアント側のプロジェクトに追加してコンパイルします.ファイル名は何でも構いません.コンパイルや実行するプロジェクトを切りかえる場合には,ワークスペースでプロジェクトを右クリック選択しアクティブに設定すればOKです.

    プログラム中のIPアドレスは,現在使用しているマシンのアドレスに変更することを忘れないように.



  7. 両方のプログラムがコンパイルできたら,サーバ側から順に実行してみましょう.



  8. 周りの誰かとペアを組み,他のマシンのサーバと通信してみましょう.クライアント側プログラムのIP設定を忘れずに.


  • 共用体



  • OpenGLにおける同期

    TCP/IPによる通信が出来るようになれば,TCP/IPで接続されているマシンどうしでコミュニケーションをとることが原理的に可能となります.上でやってきたことは,記号レベルでの通信でしたが,これをつきつめていくと文字にとどまらず画像メディアや触覚メディアの伝達もできることでしょう.

    さて,勉強会の最後のテーマは,OpenGLにおける映像メディアの伝送(同期)です.複数のコンピュータで,OpenGLの映像をシンクロさせる技法について述べます.なぜ映像の伝送の必要があるのか簡単に触れておきますと,



    というケースを想定しています.


    おわりに

    本勉強会は,OpenGLを映像生成ツールとして使用する目的で実施しました.ツールというのは結局は使う人次第です.この勉強会がきっかけで,ツールを少しでも使えるようになれば幸いです.

    お気づきの点がありましたら,ご意見を賜りたく思います.次年度勉強会の参考にします.

    戻る