| 目次| 1234567891011121314
| 資料| 予定| 課題| 宿題|

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

インターネット上の多くのサービスは,サーバ・クライアントモデルで作られ ている.要求を出すのがクライアント,それにしたがってサービスを提供する のがサーバである.一般的に一対多の通信をする場合は,一の方がサーバ,多 がクライアントと思って良い.以下に,各種のサービスについてのサーバ,ク ライアントの例をあげる. インターネット上の通信する場合の通信相手は,32ビットのIPアドレス,16 ビットのポート番号,通信の種類で指定する.これらの組合わせが電話番号の ようなものだと思ってよい.
IPアドレス
インターネットにつながったマシンに一つづつついた 32ビットのアド レス.「160.193.16.5」のように8ビットづつ10進数で並べてあらわす. 「http://160.193.16.5/index.html」のようにURLの中でも使えるが通 常は「www.ex.media.osaka-cu.ac.jp」という覚えやすいホスト名の 方を使う.IP アドレスとホスト名の変換には DNS(Domain Name System)サーバと通信しておこなう(これまたサーバクライアントモデル で動く).
ポート番号
提供するサービスによって区別される番号.Linuxでは標準的なポート 番号は/etc/servicesに書かれている.1023以下の番号は特権ポートといって, スーパーユーザ以外は使うことができない.それ以外のポート番号は,早い者 勝ちで使うことができる.
通信プロトコルの種類
ストリーム型通信のTCP,パケット型通信のUDPの2種類があるが,TCPの 方がプログラミングがやさしく,また多くのサービスが TCP で提供され てるので,この授業では TCP だけを扱うことにする.

手でサーバと通信してみる

TCPのサービスをおこなうサーバとは,telnetを使って手で通信してみることが できる.telnetは,通常は
telnet ホスト名
で,遠隔ログインするために使うコマンドだが,
telnet ホスト名 ポート番号
とやると,他のサーバと通信することができる.たとえば,WWWサーバと通信して みよう.
% telnet www.ex.media.osaka-cu.ac.jp 80
Trying 160.193.16.5...
Connected to yebisu.ex.media.osaka-cu.ac.jp.
Escape character is '^]'.
GET /~onisi/index.html
      <html>

      <head>
      <title> My First Step
      </head>

      <body>
      <H1>はじめての HTML
      HTML の文章って,かぎ括弧がやたらと多いと思いませんか?

      <A HREF="second.html"> 次のファイ ル 

      <A HREF="http://www.ex.media.osaka-cu.ac.jp/">
      情報処理教育自習室のページ

       <A HREF="http://www.ex.media.osaka-cu.ac.jp/~a00t905/">かじわら
      </body>

      </html>
Connection closed by foreign host.
こちらからどのような,コマンドを入れれば良いかというサーバごとの通信 手段はプロトコルと呼ばれる.たとえば,WWWサーバとの通信で使われるプロ トコルはHTTP(HyperText Transfer Protocol)と呼ばれる.これらのプロトコ ルのうち,標準的なものはRFC(Request for Comments)という形で文書化され ている.

クライアントプログラムの作成

さきほど,telnet を使って手動でおこなったクライアント側の動作を実行す るプログラムを Java で書いてみることにしよう.まず,ネットワークを扱う ためのクラスは,java.net パッケージ中に含まれている.TCPで通信をする時 のクライアントプログラムを作る際には,まず,ホスト名とポート番号を指定 して,Socket クラスのインスタンスを作り,できたソケットから入出力をお こなうための,ストリームを作る.実際の例をみてみよう.
 java ホスト名 ドキュメント名
とやって,HTTPファイルを標準出力に表示するプログラムを作ってみる.
     1	import java.io.*;
     2	import java.net.*;
     3	
     4	public class HttpDemo{
     5	    public static void main(String[] args) {
     6		try {
     7		    String webserver=args[0];
     8		    int http_port=80;
     9	
    10		    Socket sock=new Socket(webserver,http_port);
    11		    BufferedReader dis=new BufferedReader
    12			(new InputStreamReader(sock.getInputStream()));
    13		    PrintWriter ps=new PrintWriter(sock.getOutputStream(),true);
    14	
    15		    ps.println("GET "+args[1]);
    16		    
    17		    String s=null;
    18		    while((s=dis.readLine())!=null){
    19			System.out.println(s);
    20		    }
    21		    sock.close();
    22		}
    23		catch (Exception e) {
    24		    System.out.println("Exception: " + e);
    25		}
    26	    }
    27	}
7,8行目
コマンドライン引数と指定されるWWWサーバと通常のポート80を指定
10行目
WWWサーバプログラムと通信するためのソケットを作成
11,12行目
作成したソケットから入力(11),出力(12)用のストリームを作成
15行目
WWWサーバに「GET ドキュメント名」という文字列を送信
17,20行目
入力ストリームから入力がある間ループをまわって応答を表示
これを実行してみると以下のようになる.
% java HttpDemo www.ex.media.osaka-cu.ac.jp /~onisi/index.html
      <html>

      <head>
      <title> My First Step
      </head>

      <body>
      <H1>はじめての HTML
      HTML の文章って,かぎ括弧がやたらと多いと思いませんか?

      <A HREF="second.html"> 次のファイ ル 

      <A HREF="http://www.ex.media.osaka-cu.ac.jp/">
      情報処理教育自習室のページ

       <A HREF="http://www.ex.media.osaka-cu.ac.jp/~a00t905/">かじわら
      </body>

      </html>

簡単なサーバプログラムの作成

以下の例は,簡単なクライアント・サーバアプリケーションです.クライアン トはサーバに接続して,乱数を取得し,それを表示します.
 1	import java.io.*;
 2	import java.net.*;
 3	import java.util.*;
 4	
 5	class ServerSocketDemo {
 6	
 7	  public static void main(String args[]) {
 8	    try {
 9	
10	      // ポートを取得する
11	      int port = Integer.parseInt(args[0]);
12	
13	      // 乱数ジェネレータを作成する
14	      Random random = new Random();
15	
16	      // サーバーソケットを作成する
17	      ServerSocket ss = new ServerSocket(port);
18	
19	      // 無限ループを作成する
20	      while(true) {
21	
22	        // クライアントからの要求を受け取る
23	        Socket s = ss.accept();
24	     
25	        // 結果をクライアントに書き込む
26		PrintWriter ps = new PrintWriter(s.getOutputStream(), true);
27	        ps.println(random.nextInt());
28	     
29	        // ソケットをクローズする
30	        s.close();
31	      }
32	    }
33	    catch (Exception e) {
34	      System.out.println("Exception: " + e);
35	    }
36	  }
37	}
上のリストは,サーバプログラムのものです.コマンドライン引数して,この サーバがクライアントからの要求を監視するソフトウェアポートを1つ指定し ます.mainメソッドは最初に,引数として指定された文字列をint型に変換し, その値をportに保存します(11).次に乱数ジェネレータを作成し(14),指定されたポー トにServerSocket()オブジェクトを作成します(17).サーバはその後,無限ループ に入り(20),accept()メソッドを呼び出して,クライアントからの接続要求を待ち ます(23).要求が到着すると,accept()メソッドからSocketオブジェクトが返され ます.このソケットはクライアントとの通信に使います.データ出力ストリー ムをソケットから取得し(26),乱数をクライアントに書き込みます(27).最後にソケッ トをクローズし(30),再び,accept()メソッドを呼び出します.

簡単なクライアントプログラムの作成

 1	import java.io.*;
 2	import java.net.*;
 3	
 4	class SocketDemo {
 5	  public static void main(String args[]) {
 6	    try {
 7	      // サーバーとポートを取得する
 8	      String server = args[0];
 9	      int port = Integer.parseInt(args[1]);
10	
11	      // ソケットを作成する
12	      Socket s = new Socket(server, port);
13	
14	      // サーバーから乱数を読み取る
15	      BufferedReader dis=new BufferedReader
16		  (new InputStreamReader(s.getInputStream()));
17	      String str = dis.readLine();
18	      int i = Integer.parseInt(str);
19	
20	      // 結果を表示する
21	      System.out.println(i);
22	
23	      // ソケットをクローズする
24	      s.close();
25	    }
26	    catch (Exception e) {
27	      System.out.println("Exception: " + e);
28	    }
29	  }
30       }
このリストは,クライアントプログラムのものです.コマンドライン引数とし て,サーバの名前とポートの二つを指定します(8,9).サーバプログラムと通 信するために,Socket オブジェクトを作成します(12).このソケット用にデー タ入力ストリームを作成し(15),サーバが生成した乱数を読みとります (17,18).最後に,結果を表示して(21)ソケットをクローズ(24)します. iTermを使っている場合にこのアプリケーションで相互に通信す る方法を述べます.まず,iTermのウィンドウを開いて次のコマンド(下線部)を 入力し,サーバプログラムを起動します(BluJからは実行しない事).
% java ServerSocketDemo 4321 
"4321"は送られてくる要求の到着先となるソフトウェアポートです.ポート番 号は"4321"でなくてもかまいません.ただし,1024より下の番号は避けてくだ さい.次にもう一つiTermのウィンドウを開いて次のコマンド(下線部) を入力し,クライアントプログラムを起動します.もしくはBluJのmainメソッド呼出で「{"127.0.0.1","4321"}」を指定する.
% java SocketDemo 127.0.0.1 4321
IPアドレスの"127.0.0.1"は,ローカルマシン(自分自身)を表します.2番目の 引数はサーバプログラムの引数として指定した番号と同じ番号を指定しなけれ ばなりません(この場合"4321").SocketDemo プログラムは,乱数を表示する と終了しますが,再度このプログラムを実行すれば,別の乱数を取得できます.


| 目次| 1234567891011121314
| 資料| 予定| 課題| 宿題|