静岡理工科大学 総合情報学部 (by 菅沼) 菅沼ホーム 目次 演習解答例 付録 索引

第W部

第19章 Networkプログラミング

  1. 19.1 ソケットの利用
  2. (プログラム例 19.1 ) HTTP ポート
  3. (プログラム例 19.2 ) ファイルの転送
  4. (プログラム例 19.3 ) チャットルーム
  この章においては,Network プログラミングについて概説します.非常に基本的なことに対してだけの説明ですので,詳細については,他の書籍及び付録等を参照してください.

19.1 ソケットの利用

  オペレーティングシステム( OS )の処理の単位をタスク,プロセス,スレッドなどと呼びます.呼び方は OS によって異なると共に,多少その意味は異なりますが,ここではほとんど同じ意味で使用していきます.

  2 つのプロセス間でデータ交換を行なうことをプロセス間通信( IPC,InterProcess Communication )といいます.通信を行なう 2 つのプロセスは,同一のシステムに存在しても,ネットワーク間に存在しても構いませんが,一般に,通信を行うためには,通信路が必要です.その際利用されるのがソケットです.ソケットとは,TCP/IP において利用するネットワーク用 API のことを指します.まず,ここで,TCP/IP 等について簡単に説明しておきます.

  TCP や UDP で通信をする場合,まずソケットを使って通信路を確保し,通常のファイル入出力用の read / write などを使って通信を行います.通信路を確保してしまえば,ファイル入出力と全く同じ感覚でプロセス間通信を行えます.

  通信路を確保する際,TCP や UDP では,アプリケーションまたは上位のプロトコルに対して,データの送受信を行うためのアドレスは,符号なし整数で表わされます.このアドレスをポート(番号)と呼びます.電子メールや FTP などのプロセス間通信用のアプリケーションにおいては,使用するポートが決まっています.このように,ポートには,アプリケーションが任意に使用可能なポートのほか,電子メールのような特定のアプリケーションが使用する Well-known ポートと呼ばれるものがあります.Well-known ポートでは,特定のアプリケーションのために使用することが予約されており,その番号とアプリケーションの対応は,NIC ( Network Information Center )によって統一的に管理されています.また,1 〜 1023 番のポートは予約ポートと呼ばれ,これらのポートを UNIX などで使用するには,ルートの権限が必要になります.なお,代表的な Well-known ポートには,以下に示すようなものがあります.

ポート番号 ポート名 用途
20 ftp data File Transfer Protocolのデータ用ポート
21 ftp File Transfer Protocolの制御用ポート
23 telnet Telnet Protocol
80 http http
25 smtp Simple Mail Transfer Protocol
110 pop3 Post Office Protocol version 3
119 nntp Network News Transfer Protocol
123 ntp Network Time Protocol

(プログラム例 19.1 ) HTTP ポート

  サーバとクライアントのプロセス間で通信を行うためには,両者において,通信を行うためのプロセスが動作している必要があります.電子メール,ftp,http などが使用する Well-known ポートにおいては,通常,サーバ側のプロセスは常に動作しています.また,クライアント側においても,クライアント側のプロセスを起動するためのプログラムは OS によって準備されています.したがって,クライアント側で,適切なプログラムによって必要なプロセスを起動してやれば,プロセス間通信を行えます.たとえば,ftp においては,ftp コマンドを使用することによって簡単にプロセス間通信を行えますし,また,ホームページを閲覧するためには,Internet Explorer などのブラウザを起動することによって,HTTP ポートを利用したプロセス間通信が可能になります.

  しかし,Well-known ポートに対しても,クライアント側のプログラムを特別に書き,サーバ側のプロセスとのプロセス間通信を行うことが可能です.例に示したプログラムは,http ポートを利用し,ファイル「 http://cs-www/~suganuma/index.html 」の内容(テキストデータだけ)を表示するためのものです.

  まず,c_setup 関数内において,socket 関数によってソケットを作成し,connect 関数によってサーバに接続しています.main 関数では,サーバ側のプロセスに対して以下に示す文字列(リクエスト.コメント部分は除く)を送信( write 関数)することによって,指定したファイルの内容を送信してもらい,その結果をクライアント側の画面に表示しています( while 文).一般的には,Well-known ポートに対してこのようなプログラムを書くことはないと思います.
	GET /~suganuma/index.html HTTP/1.1\r\n  // 送信内容の指定
	Host: cs-www:80\r\n  // ホスト名とポート
	\r\n  // リクエスト(GET)の終了
		
(プログラム例 19.2 ) ファイルの転送

  次に,一般的なソケットの使用方法について考えてみます.ここで示す例は,クライアント側のファイルをサーバ側へ転送するためのプログラムです.ファイル転送を行う場合は,このようなプログラムを書かずに,ftp ポートを利用した ftp コマンドを利用することの方が実際的です.

  まず,クライアント側のプログラムを見て下さい( ).サーバ名や送信するファイル名を入力する点,ポート番号( 50000 ),ファイル内容の送信等の点で多少異なっていますが,基本的には,プログラム例 19.1 と同じです.

  次に,サーバ側のプログラムを見て下さい( ).まず,c_setup 関数内において,socket 関数によってリスニングソケットを作成し,bind 関数によってサーバのアドレスをソケットに設定し,次に,listen 関数によって接続待ちの状態に入ります.

  main 関数では,クライアント側からの接続要求に対して,accept 関数によって接続済みソケットを作成します.最も簡単にプログラムを書くとすれば,この時点でクライアントから送られてきたデータをファイルとして保存するようにすれば,ファイルの転送は終了します.しかし,このままでは,複数のクライアントから要求があった場合への対応が不十分になります(処理中のクライアントに対する処理が終了しない限り,次のクライアントの処理が行えない).

  そこで,この例では,fork 関数を使用して子プロセスを生成し,ファイル転送に関わる実際の処理は子プロセスで行うようにしています.fork 関数によって子プロセスを生成すると,右図に示すように,親プロセス及び子プロセスが,リスニングソケットと接続済みソケットで接続された状態になります.そこで,待ち受けだけを親プロセスで行い,ftp に関する実際の処理を子プロセスで行うため,親プロセスでは接続済みソケットを閉じ(×印),また,子プロセスではリスニングソケットを閉じ(×印)た後,e_ftp 関数によってファイル転送処理を行っています.ファイル転送処理を終了すると,子プロセスが終了すると共に,子プロセスの接続済みソケットも閉じられます.

(プログラム例 19.3 ) チャットルーム

  この例では,チャットルームを取り上げます.まず,クライアント側のプログラムを見て下さい( ).接続までは,基本的に,プログラム例 19.2 と同じです.接続後,クライアント側には,サーバ側またはキーボードから情報が入ってきますので,どちらからの情報かを識別する必要があります.そのために,prepare 関数内で,キーボード及びソケットからの情報を受け取れるように設定します.

  チャットは,chat 関数内で行われます.select 関数(プログラム内で使用されている FD_ZERO,FD_SET,FD_ISSET,FD_CLR などに関しては,この関数の説明を参照)によって,どこからの情報かを調べます.キーボードから入力された場合は,入力されたデータをそのままサーバに送ります.チャットルームから出るために quit を入力した場合も,そのままサーバに転送します.また,ソケットを介したデータの場合は,受け取ったデータをそのまま画面に表示します.ただし,終了メッセージの場合( quit を含む)は,接続を閉じます.

  次に,サーバ側のプログラムを見て下さい( ).リスニングソケットを作成するまでは,チャットルームへの最大参加者数を入力する点以外は,基本的に,プログラム例 19.2 と同じです.次に,参加者登録簿を作成した後,キーボードからの入力とソケットからのデータとを識別するために使用するマスクを設定します.

  クライアント用のプログラムと同様,チャットは,chat 関数内で実行されます.select 関数によって,どこからの情報かを調べます.サーバの場合,以下に示す 3 つの場合が存在します.一つは,リスニングソケットからのデータの場合です.この場合は,accept 関数によって接続済みソケットを作成します.もし,チャットルームが満員の場合は,メッセージを送信し,接続を閉じます.そうでない場合は,名前の入力を促すメッセージを送信した後,接続済みソケットを登録します.

  2 番目は,キーボードからの入力の場合です.このプログラムでは,チャットルームを閉じるための quit という入力しか認めていません.キーボードから quit が入力されると,チャットルームを閉じるメッセージをすべての参加者に送信した後,すべての接続済みソケットとリスニングソケットを閉じます.最後は,接続済みソケットからのデータの場合です.ソケットを介して受信したメッセージが quit であった場合は,対象となるクライアントとの接続を閉じ,参加者リストから外します.そうでない場合は,送られてきたメッセージを,全参加者に送信します.

静岡理工科大学 総合情報学部 (by 菅沼) 菅沼ホーム 目次 演習解答例 付録 索引