UNIX 講習会 (6)

目次へ

Last modified: Wed Aug 8 16:01:59 2001

2001/7


6. UNIX のネットワークについて

基本

どのような電気通信でも、最終的にはデータはすべて電気信号に変換される (じつは電気ではなくてハトを使った通信方式も提案されている。 詳しくは ここ を見よ)。 そしてそのための方式 (プロトコル) はたくさんある。

UNIX では、各マシン間はすべて 「インターネットプロトコル (IP)」 によって通信する。 これはその名のとおり、現在のインターネットで一般的に使われている 通信方式である。一般に TCP/IP と呼ばれる。

(ちなみに Windows は TCP/IP のほかにも、 NetBEUI と呼ばれるまったく別の方式によっても通信できるようになっている)


TCP/IP 構造

UNIX では、各プロセスが送受信するデータは 次のような層を減て最終的に電気信号に変換される:

IP パケットを送受信できる計算機をインターネット上の ホスト (host) とよぶ。ホストは、どれも世界で唯一の IP アドレス (IP address) を持っている。

データ送受信の手順:

  1. 送り側のアプリケーションが送るデータを用意する。
  2. OS の TCP層がそのデータを IP パケットに切り分ける。
  3. OS の IP層がその切り分られたデータを、 どの回線を使って送信するか振り分ける (ふつうは 1つのホスト = 1回線であるが、 ゲートウェイなどのマシンは複数の回線を持っている)。
  4. OS の データリンク層が IPパケットをビット列として送信する。
  5. (…送られたデータはいくつかの回線を電気的に経由する…)
  6. OS のデータリンク層が IPパケットをビット列として受信する。
  7. OS の IP層がその IP パケットを受けとり、他へ転送するか このマシンで受けとるかを決める。
  8. OS の TCP層がいくつかの IP パケットをひとつにまとめる。
  9. 受け側のアプリケーションがデータを受けとる。


図 1. TCP/IP の層

注意: ふつう、ほとんどの UNIX アプリケーションはネットワーク上の データ転送に TCP を使うが、一部のアプリケーションは これとは別のプロトコルを使うこともある (UDP、ICMP など)。 これらも IP パケットの形で送られるが、送ることのできる データのサイズや信頼性で差がある。


IP の実例

IP パケットの流れ:

   学外のホスト
       | (なにかの回線)
   東工大の総合情報処理センターにある noc の中継器
       | (FDDI)
   西8号館 3階にある noc の中継器
       | (Ethernet)
   西8号館 4階にある cs の中継器
       | (Ethernet)
   西8号館 6階サーバ室にある 6階の中継器
       | (Ethernet)
   cl0 (田中・徳永研 ゲートウェイ)
       | (Ethernet)
   研究室のマシン

研究室から www.yahoo.com (204.71.200.74) への traceroute の例:

% traceroute www.yahoo.com
traceroute to www.yahoo.akadns.net (204.71.200.74), 30 hops max, 40 byte packets
 1  cl0i.cl.local (192.168.208.1)  0.238 ms  0.175 ms  0.171 ms
 2  gw.cs.titech.ac.jp (131.112.16.1)  0.69 ms  0.628 ms  0.625 ms
 3  nisi8e-gw.cs.titech.ac.jp (131.112.17.62)  1.795 ms  1.517 ms  1.376 ms
 4  fddi-gw1-f0.noc.titech.ac.jp (131.112.1.68)  1.734 ms  1.382 ms  1.266 ms
 5  uchibori-f0.noc.titech.ac.jp (131.112.253.1)  2.534 ms  2.32 ms  2.06 ms
 6  wide-gate.noc.titech.ac.jp (131.112.125.180)  3.15 ms  2.542 ms  3.053 ms
 7  cisco2.otemachi.wide.ad.jp (203.178.136.4)  7.433 ms  5.361 ms  8.283 ms
 8  foundry2.otemachi.wide.ad.jp (203.178.140.216)  11.96 ms  6.365 ms  5.232 ms
 9  as4197.nspixp2.wide.ad.jp (202.249.2.108)  7.036 ms  11.097 ms  4.909 ms
10  bbr02-p1-0.tkyo01.exodus.net (64.56.161.114)  8.386 ms  4.872 ms  4.823 ms
11  bbr02-p0-0.snva02.exodus.net (64.56.188.22)  151.712 ms  153.33 ms  152.278 ms
12  dcr01-g9-0.snva01.exodus.net (64.15.160.134)  154.667 ms  152.556 ms  154.027 ms
13  bas1r-ge3-0-hr8.snv.yahoo.com (208.178.103.62)  153.759 ms  162.316 ms  169.082 ms
14  www9.yahoo.com (204.71.200.74)  199.513 ms  155.839 ms  152.363 ms

プライベートネットワーク

IP アドレスは同じものが世界で 2つあってはならない。 しかし IP アドレスの割りあては不足しており、実際には 全世界のマシンがすべて自分の IP アドレスを持てるわけではない。 また、自分のマシンが直接外界と通じている IP アドレスを持っていると、 最近はやりのクラッカーやワームにやられたりして大変である。

そこで cs では「プライベートネットワーク (private network)」と 呼ばれるネットワークを構築している。 基本的には、これは研究室のマシンをインターネットから隔離しておき、 必要なとき (メール送受信や web ブラウズなど) だけに 外部との通信をやりとりするゲートウェイ (gateway) を置く方法である。

田中・徳永研では、外部のインターネットに直接接続しているのは cl0i (メールサーバ及びゲートウェイ) と cl1i (web サーバ) だけである。 あとのすべてのマシン (snow や soleil, あなたが今使っている端末も含む) は インターネットには直接アクセスできないし、また、されない。 これは物理的に隔離されている (田中・徳永研のスイッチングハブを見よ)。 このように隔離されたマシンは、別に外の世界と 同じ IP アドレスをもっていも構わない。 これによって形成されたネットワークを (外部から入れないという意味で) プライベートネットワークと呼ぶ。

実際にはプライベートネットワークといえども外部に通信したいことも あるわけで、研究室ではそのために特別な「プライベート IP アドレス (private IP address)」 を各マシンに割り当てている。 逆に、本物のインターネット上の IP アドレスを「グローバル IP アドレス (global IP address)」 と呼ぶ。

マシンの IP アドレスを確認する:

(godot の場合)
% /sbin/ifconfig -a
eth0      Link encap:Ethernet  HWaddr 00:90:27:5F:48:94  
          inet addr:192.168.208.15  Bcast:192.168.208.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:11798932 errors:0 dropped:0 overruns:0 frame:2
          TX packets:8322322 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100 
          Interrupt:9 Base address:0x6000 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:3924  Metric:1
          RX packets:11675822 errors:0 dropped:0 overruns:0 frame:0
          TX packets:11675822 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 

%

新山の足元に置いてあるマシン godot の IP アドレスは 192.168.208.15 である。一般に 192.168. で始まる IP アドレスは 「プライベート」であると認定されており、グローバル IP アドレスでは 使われないことが保証されている。


外部との通信

では、この場合、研究室内での web や ftp ブラウズはどのように 行うのか? たとえばホスト godot (192.168.208.15) が www.yahoo.com (204.71.200.74) と通信して web page を見たいとする:


図 2. www.yahoo.com との通信

IP アドレスと DNS

インターネット上のホストを指定するやり方は 2通りある。 ひとつは、「204.71.200.74」のように 4つの数字からなる IP アドレスで指定する方法。 もうひとつは、「www.yahoo.com」のように ピリオドで区切られたアルファベットからなる「ホスト名」で指定する方法である。 この方式は、IPアドレスが覚えにくいため開発された。

たいていの Unix のプログラムでは、ホストを指定するときに ホスト名が使われるとそれは自動的に IP アドレスに変換される。 これをホスト名の「解決 (Resolution)」 あるいは「正引き」と呼び、 このような仕組み全体を DNS (Domain Name System) と呼ぶ。 DNS はネームサーバ (Name Server) と呼ばれるプログラムによって 実現されている。 研究室内の各マシンはあらかじめネームサーバ (田中・徳永研では snow の 192.168.208.10) の IP アドレスを知っており、 ここにホスト名を送信して、IP アドレスを受けとる。 ネームサーバとの通信ができない場合はホスト名による指定は使えない。

www.yahoo.com」などのホスト名のうち、 「.yahoo.com」の部分をドメイン名 (Domain Name) とよぶ。 「.yahoo.com」のドメインをもつホスト名は、すべて そのドメイン専用の DNS サーバに IP アドレスをたずねることになっている (世界には 10個かそこらの DNS ルートサーバがあり、ホスト名は 「.」の区切りに応じて再帰的に検索される、 たとえば yahoo.com のネームサーバのひとつは 204.71.200.33 である)。

IP アドレスと同じように、ホスト名も世界に 2つと同じものがあっては いけない。ちなみに田中・徳永研のプライベートネットワークでは、 すべてのホストには「.cl.local」の ドメイン名がつけられている。ネームサーバは snow.cl.local (192.168.208.10) である。研究室外のホスト名 (www.yahoo.com など) を 解決するときは、cl0i を経由して yahoo.com のネームサーバに問い合わせ られる。

課題 1. どこか適当な学内のホストと学外のホストの IP アドレスを dnsip を使って調べなさい。

課題 2. その IP アドレスを dnsname を使って逆引きし、 結果が同じかどうか調べなさい。

ホストによっては、いくつもの DNS ホスト名が同一の IP アドレスに 写像されている場合もある。このような複数ある別のホスト名を、 そのホストの「別名 (Canonical Name)」あるいはエイリアス(Alias)という。

課題 3. そのホストに ping や traceroute を実行してみなさい。 ただし、サイトによっては、 むやみな ping や traceroute はそのサイトに対する 攻撃とみなされることもあるので注意。

課題 4. あるホストと通信しようとしているとき、IP アドレスのかわりに ホスト名で指定すると、発生しうるエラーは増える。 どのようなエラーが発生しうるか。 また、それらのエラーをどうやって区別するか。


サービスとポート番号

さて、あるデータが IP パケットを通じてどのように 転送されるのかについては、これまででほぼ説明した。 しかしインターネット上には沢山の種類のデータ (メール、www、ftp等) が 流れている。これらの各データは、OS によってどのように 区別されているのだろうか?

実は、各 IP パケット (正確には TCP パケット) には 送り元、送り先の IP アドレスとともに、

も書かれている。

インターネット上のホストはすべて 65535個の仮想的な 「ポート (port)」を持っており、TCP による通信は 正確には各ホスト間ではなく「各ホストのポート間」で おこなわれる。そして、ある特定のサービスは必ず決められた ポート番号で通信する慣例になっている。 これは RFC で決められているので、ふつう web クライアント (Netscape、IE等) は「www.yahoo.com にアクセスせよ」と命令されると www.yahoo.com の 80番ポートにアクセスしようとする。しかしこのとりきめは 絶対ではなく、たとえば田中・徳永研の web サーバ上では 80番以外に 8000番でも web サービスを行っている。このように標準でないポートに アクセスする場合、その URL 指定は、 http://tanaka-www.cs.titech.ac.jp:8000/ のようになる。


図 3. TCP の仮想ポート

TCP/IP を使った通信では、必ずどちらか一方が「サーバプロセス」で、 もう一方が「クライアントプロセス」でなければならない。 ふつうサーバプロセスは特定のポート番号でクライアントからの 接続を待っている (listen)。そこにクライアントが接続して何か 要求する、という形が一般的である。

各サービスを実施するサーバプロセス (httpd, smtpd など) は それぞれサービスごとに慣例によって決められたポートを使う。 たとえば図 3 では、クライアントである Host2 が、自分の 4021番ポートから サーバである Host1 の 80番ポート (ここではふつう web サーバが待っている) に 接続している。

「現在、どのポートがどのポートに接続しているか」は netstat コマンドを使うと見ることができる:

% netstat -an
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address        Foreign Address      State       
tcp        0      0 192.168.208.15:4021  204.71.200.33:80     ESTABLISHED 
tcp        0      0 192.168.208.15:6000  192.168.208.15:4019  ESTABLISHED 
tcp        0    248 192.168.208.15:4019  192.168.208.15:6000  ESTABLISHED 
tcp        0      0 192.168.208.15:6000  192.168.208.15:4015  ESTABLISHED 
tcp        0      0 192.168.208.15:4015  192.168.208.15:6000  ESTABLISHED 
tcp        0      0 192.168.208.15:6000  192.168.208.15:4014  ESTABLISHED 
tcp        0      0 192.168.208.15:4014  192.168.208.15:6000  ESTABLISHED 
tcp        0      0 192.168.208.15:6000  192.168.208.15:3964  ESTABLISHED 
tcp        0      0 0.0.0.0:6000         0.0.0.0:*            LISTEN      
tcp        0      0 0.0.0.0:80           0.0.0.0:*            LISTEN      
tcp        0      0 0.0.0.0:1024         0.0.0.0:*            LISTEN      
tcp        0      0 0.0.0.0:679          0.0.0.0:*            LISTEN      
tcp        0      0 0.0.0.0:22           0.0.0.0:*            LISTEN      
tcp        0      0 0.0.0.0:21           0.0.0.0:*            LISTEN      
tcp        0      0 0.0.0.0:2003         0.0.0.0:*            LISTEN      
tcp        0      0 0.0.0.0:513          0.0.0.0:*            LISTEN      
tcp        0      0 0.0.0.0:514          0.0.0.0:*            LISTEN      
tcp        0      0 0.0.0.0:23           0.0.0.0:*            LISTEN      
tcp        0      0 0.0.0.0:111          0.0.0.0:*            LISTEN      

ここで「LISTEN」と表示されているポートは、 ここでサーバが待っていることを示す。これを見ると、godot では Xサーバ (ポート番号 6000) のほかに web サーバ (ポート番号 1024)、 SSH サーバ (ポート番号 22) なども動いていることがわかる。

(IPアドレスとホスト名の関係と同じように、ポート番号も 「サービス名 (service name)」と呼ばれる名前によって指定できる。 この関係は/etc/services に記述されているが、これが 全てではない)


いろいろなサービスの中身

FTP (ポート番号 21)
ファイル転送用プロトコルで、HTTPとは違って途中から再開できる。
SSH (ポート番号 22)
ようするに、暗号化された遠隔ログイン。
TELNET (ポート番号 23)
代表的な遠隔ログイン。やってみればわかる。
SMTP (ポート番号 25)
メールを送るサービス。インターネット上に送られる すべてのメールは、このプロトコルを使って処理されている。
HTTP (ポート番号 80)
知らないわけがない。
RPC (NFS, NIS) (ポート番号 111 ほか)
異なるホスト間での手続き呼び出し (Remote Procedure Call) を おこなうためのプロトコル。これを使うと別のホストのファイルを 開けたり (これが NFS)、別ホスト上にあるパスワードで ログインできたりする (これが NIS)。田中・徳永研で どのマシンにも同一のパスワードでログインでき、 同一のホームディレクトリにアクセスできるのは このプロトコルのおかげである。
LOGIN (ポート番号 513)
TELNET と違い、信頼しているホスト間ではパスワードを入力しなくてもよい。
X11 (ポート番号 6000〜)
画面描画のためのサービス。
DNS (ポート番号 UDP 53)
ホスト名から IPアドレス を調べる (正引き)、あるいは IP アドレスからホスト名を調べる (逆引き) サービス。 ふつう DNS は TCP ではなく、UDP を使っている。

課題. snow の SMTP ポートに telnet して、直接自分にメールを送ってみよう。

課題. tanaka-www の HTTP ポートに telnet して、直接 web ページを読んでみよう。

課題. 自分の端末から snow に rlogin して、それぞれの ホストで netstat -a を実行してみよう。あるいは xon を実行してみよう。 それぞれのホストの513番ポートと 6000番ポートの接続状況はどうなっているか。


X Window System について

UNIX では、画面に対する描画も究極的にはネットワークを使って 行っている。たとえば Vectra や ACC といった端末を使って snow で kterm や mule を起動する場合、画面描画はすべてネットワーク経由で snow が行っており、キーボードの入力もネットワーク経由で snow に送られている。このように TCP/IP を使ってグラフィカル インターフェイスを実現する仕組みを X Window System (X11) とよび、 そのための通信形式を X と呼ぶ。

X を使うときは 2つのプログラムがいる。 ひとつは X クライアント (X client) で、 もうひとつは X サーバ (X server) である。 「X クライアント」は X の機能を使って画面に何かを描く アプリケーション、つまり kterm とか netscape とかのことで、 X サーバに対して画面の描画やマウス座標の読みとりを指示する。 いっぽう「X サーバ」は、X クライアントの要求を受け、 実際にディスプレイ上のピクセルを表示するプログラムである。 ふだんは意識しないが、ふつう X を使っている端末 (田中・徳永研では、 ACC や Vectra) 上ではつねに X サーバが動いている。そして X クライアントのネットワーク上からの要求に応じている。 X の仕組みをよく理解せずに使っていると、kterm や netscape が 画面をすべてコントロールしているかのように思えるが、実際には これらはただ仮想的な画面に対して「描画命令」を送っているだけだ。 実際に画面を描画しているのは X サーバである。

また、キーボードやマウスからの入力もすべて 実際に処理しているのは X サーバである。これらは X プロトコルを介してネットワーク上に送られ、kterm や netscape が受けとることになる。

X サーバは X のプロトコルを理解し画面を書きかえさえすれば よいので、実際には何の計算もしていない。現在では PC 上 (Windows 上) でも走る X サーバがある。

問. Windows や Mac のアーキテクチャでは、 「画面になにか描く」という行為はひとつのプロセスだけで すべて行えるのに、なぜ UNIX ではこのように画面の描画を サーバ側とクライアント側に分けるのか? このメリットは何か?

注意してほしいのは、「X クライアント」と「X サーバ」の意味が 混乱しやすいこと。ふつう UNIX でクライアントとサーバといえば、 UNIXの動いている機械がサーバであり、端末(あるいはPC)が クライアントのように見える。しかしクライアントとサーバの 元々の意味を考えてみよう。 つまりクライアントとは命令する人のことであり、 サーバがそれにお仕えする(serveする)人だ。 なので、X の観点からいうと命令するのは UNIX 上で走っているプロセス であり、よってこれらは X の命令をする「クライアント」と呼ばれる。 この命令を受けるのは端末なので、「Linux 端末では X サーバが 動いている」といったいい方をする。

これらの X クライアントと X サーバは互いに「X プロトコル」と 呼ばれる形式で通信する。これは通常 TCP/IP 6000番ポートを 介しておこなっている。詳しいプロトコルは知らなくても、 UNIX では Xlib というライブラリを使えば、そいつが自動的に ネットワーク接続して相手の X サーバに描画命令を出してくれる。 X クライアントはすべてこのライブラリを使っている。

ちなみに、X クライアントが接続している X サーバを、 そのクライアントの「ディスプレイ (display、画面装置)」と呼ぶ。 この接続で使われるのが環境変数 DISPLAY である。 DISPLAY には 「ディスプレイ(Xサーバ)の名前:ディスプレイ番号」が 入っている。 たとえば「godot.cl.local:0.0」など。 Xlib を使っているプログラム (= X クライアント) は、この環境変数の 値を見てどの X サーバを使うかを決めるのだ。 逆に DISPLAY の値が設定されていないと、 X のアプリケーションは使えない (その場合も kterm などは -d オプションでディスプレイを 指定できるが)。

しかし、ここでひとつ問題がある。 ふつう X の通信は TCP/IP を使っているので、ある X サーバは どのホストからでも接続してコントロールできてしまう。なぜなら TCP/IP では、接続元のホストで誰がそのプロセスを実行しているのかまでは 判別できないからだ。 つまり X サーバにとってはユーザを識別する手段がないから、 あるホストからのコントロールを本当に受けつけてしまっていいかどうか わからない。しかしどんな接続でも受けつけてしまうのは危険だ。

問. なぜ X の接続を受けつけてしまうと危険なのか? どこかのディスプレイで xhost + を実行しておき、 xwd -display そのディスプレイ -out hoge; xwud -in hoge; を実行してみよう。

そこで、実際には X に接続するときは認証をおこなう必要がある。 これはちょっとややこしいんだけど、 現在はいくつかの方式がサポートされている。

さて、X ではもうひとつ重要な概念として 「ウインドウマネージャ (Window Manager)」がある。 ふつう、X のクライアントは単独では使わず、かならず ひとつのディスプレイ上にひとつのウインドウマネージャを走らせる。 これは、X のウインドウ処理があまりに質素なため、 X のクライアント単独ではウインドウの大きさを変えたり 移動させたりもできないからだ (ためしにウインドウマネージャを 終了させてみるとわかる)。X では純粋なウインドウとは ただの箱で、そこには移動させるための枠などついていない。 これは実は意図的にやっていることで、 「純粋に描画機構のみを提供し、意味は押しつけない」というのが X のポリシーである。つまりウインドウの枠がクリックされたら 何が起こるべきか、などの思想は、 アプリケーションが決めるべきだというのだ。

問. このように純粋な描画とインターフェイスを 分離することで生まれるメリットはなにか。

ウインドウマネージャは特殊な処理をして、各 X クライアントの 情報を「横取り」し、そこに枠の描画などの処理を加える (が、ウインドウマネージャもただの UNIX 上の 1プロセスである)。 最近ではウインドウマネージャと融合した Windows のエクスプローラのようなプログラム (デスクトップ上に ファイルを表すアイコンを表示する) も存在する。 田中・徳永研ではだれも使ってないけど。

X のビットマップはどこで作られているのか?

これはふつうはすべて X サーバ上である。 X では、描画命令は手続き的に送られる。 つまりクライアントは 「どこに文字を描け」だの「どこからどこまで線を引け」だの といった命令を送るだけで、実際のビットマップを送ることはしない (なぜならそんなことをするとネットワークに送るべき データ量が途方もなく大きくなり、遅くなってしまうから)。 けれども X クライアントが ビットマップそのものを直接送って 表示させることもできる (当然おそい)。X のプロトコルは なるべく余分な通信が少なくてすむように設計されている。

問. ふだん使っている 1280x1024、65000色 (2^16bit) の 画面内容をすべてそのままネットワークに送るとどれくらいの バイト数を転送しなければならないか。

X では、フォントに関する問題もややこしい。 ふつう X で使う文字フォントは、クライアントではなく X サーバが持っている (フォントのビットマップを 1文字1文字送っていると効率悪い)。 ただし凝った画面をもつアプリケーションは、 クライアント側で全部画像を作ってしまって、あとはそれを X サーバに 送るだけ、というのもある。

以下の図 4〜8 は さまざまな状況における X の動きを示したものである。


図 4. Xを使っていないUNIXと使っているUNIX


図 5. kterm上で ls を実行した場合


図 6. kterm上で mule を実行した場合


図 7. kterm上で別のマシンに rlogin した場合


図 8. 別々のマシンでktermを起動した場合

TCP を使ったアプリケーションを作る

Perl を使えば、TCP を使って通信するプログラムを簡単に作ることができる。

クライアント側のプログラム client :

#!/usr/local/bin/perl
use Socket;
$HOST = $ARGV[0] || 'localhost';
$PORT = $ARGV[1] || 10000;
$PROTO = getprotobyname('tcp');
# 通信の端点となるソケット S を作成する。
socket(S, PF_INET, SOCK_STREAM, $PROTO) || die("socket : $!");
# サーバのホスト名から IP アドレスを解決する。
$ent = sockaddr_in($PORT, inet_aton($HOST));
# サーバに接続する。以後ソケット S はファイルと同様に読み書きできる。
connect(S, $ent) || die("connect : $!");
# ソケット S のバッファリングを禁止する。
select(S); $| = 1; select(STDOUT);

print S "hogehoge\n";
$a = <S>;
print $a;
exit;

サーバ側のプログラム server :

#!/usr/local/bin/perl
use Socket;
$PORT = $ARGV[0] || 10000;
$PROTO = getprotobyname('tcp');
# 通信の端点となるソケット S を作成する。
socket(S, PF_INET, SOCK_STREAM, $proto) || die("socket: $!");
# 特定のポート番号にソケットを結びつける。
$ent = sockaddr_in($PORT, INADDR_ANY);
bind(S, $ent) || die("bind: $!");
# そのポートで listen 開始。
listen(S, 5) || die("listen: $!");

for(;;) {
    # クライアントが接続してくるのを待つ。
    accept(C, S);
    if (!fork()) {
	# クライアントが 1つ接続してくるたびに、子プロセスをforkする。
	# 子プロセスの処理:
	print "connected.\n";
	select(C); $| = 1; select(STDOUT);
	while(<C>) {
	    print "$_\n"; print C "received: $_\n";
	}
	print "closed.\n"; 
	exit;
    } else {
	# 親プロセスの処理:
	close(C);
    }
}

はじめに、どこかのホスト上で server を起動しておく。 このプログラムは、通常ポート番号 10000番でクライアントの接続を 待つようになっている (ちなみにひとつのポート上では 1度に 1つのプロセスしか listen できない。snow などで server プログラムが 起動できない場合は、だれかがすでに 10000番ポートを「使用中」である 可能性がある。そのような場合は server に引数を与えて異なる 番号のポートを指定すること。なお Unix では、1024番未満のポート番号は 一般ユーザが listen することはできない)。

つぎに、同一または別のホスト上から client を実行する。 「% client ホスト名 ポート番号」 のようにすれば、 指定されたホストの指定されたポートに接続する。 このプログラムはサーバに「hogehoge」という文字列を送り、 サーバからの出力を返すだけなので、うまく動けば 画面に「received: hogehoge」という文字列 (これはサーバ側が 送り返した文字列である) が表示されるはずである。

課題. 上の server プログラムに telnet を使って同時に 複数接続してみなさい。

課題. サーバプログラム server は、 クライアントがひとつ接続してくるたびに fork (子プロセスを分裂) する。 なぜこのような機構が必要なのか考えなさい。コードを改造し 「if (!fork()) { 〜 } else { close(C); }」の if 文を除いて、子プロセスが fork しないようにして どのような変化が起きるか観察しなさい。

課題. 上のプログラム server を使って、Netscape の web クライアントが送る HTTP リクエストがどのようなものであるかを 調べなさい。どうすればできるか?

課題. 上のプログラム 2つを組み合わせて簡易 web プロキシをつくりなさい。 「GET」「HEAD」「POST」のメソッドを受けつけ、接続先のホストに HTTP リクエストを転送する。その後、返された文字列を クライアント側に送り返す。

課題. TCP における通信は、ひとつのサーバに同時にいくつもの クライアントが接続しても通信が混線しない。どういう仕掛けによって 実現されているのだろうか。考えよう。


研究室のネットワークに参加する

電話をかけて接続する方法:

電話を使って TCP/IP 通信をする場合、 データリンク層として Ethernet のかわりに PPP (Point-to-Point Protocol) を使う。

Ethernet に接続する方法:

Ethernet は基本的にすべてブロードキャストで通信するため、 研究室のネットワークではどこにつないでもすべてのマシンと 通信できる。そのため、余分な設定は何もする必要がない。

無線LAN に接続する方法:

無線 LAN は電波を使っているだけで、 やっていることは基本的に Ethernet と同じである。ただし 無線 LAN の場合は無線を受信して、実際の線 (Ethernet) に 中継する機器 (無線LANステーション と呼ばれる) が必要である。 田中・徳永研では無線LANステーションとして AirMacを使っており、これは2つの部屋に置かれている。 なお、セキュリティ上の理由から研究室では あらかじめ番号登録された無線LANカードしかEthernetに中継できない。 なぜかはわかるよね。

DHCPを使う:

TCP/IP を使うには、お互いホストのアドレスが あらかじめ決まっている必要がある。Ethernet を使っている 場合、通信はどこからどこへでも行えるので IP アドレスというのは純粋にソフトウエア的なものである。 「自分のIPアドレスを変える」というのは、IPパケットに 書く数値を変えるだけでできてしまう。しかし、誰かが 持ちこんだノートパソコンに勝手な IP アドレスを名乗られては 困るので、研究室では Ethernet にさえつながっていれば IP アドレスを自動的に割りふる DHCP (Dynamic Host Configuration Protocol) とよばれるものを使っている (アドレスの決まっていない段階ではまだ TCP/IP は使えないので、 DHCP は Ethernet 上に直接送られるプロトコルである)。 TCP/IP の設定を DHCP にしておけば、研究室の DHCPサーバが 自動的にそれを検知してアドレスを割りあててくれる。しかし こうすると IP アドレスは毎回変わる可能性があるので、 本気でデスクトップ機をもち込んで運用したい人は 管理者に頼んで固定IPアドレスをつけてもらおう。

ネットワークの危険性とSSH:

Ethernet や無線 LAN では、情報はすべてブロードキャストされる。 これは逆に言えば、誰にでも見られてしまう危険性があるということだ。 実際、無線 LAN の盗聴は簡単にできる。 無線 LAN を使ってログインするときは暗号化のためにSSH を使うこと。


^ front   新山 祐介 euske@cl.cs.titech.ac.jp