ASH | サーバ | セキュリティ | Linux | FreeBSD | DB | Web | CGI | Perl | Java | XML | プログラム | ネットワーク | 標準 | Tips集

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

 ネットワークプログラムの方法の初歩について説明します。

ネットワークプログラムの概要

 ネットワークプログラムには、コネクション型とコネクションレス型がありますが、ここでは、コネクション型を利用します。 通信をする場合、データを提供する側のコンピュータをサーバといい、データを参照する側のコンピュータをクライアントと呼びます。
 Hello サーバという、クライアントから接続されると "Hello world." を出力するサーバと、Hello サーバに接続し出力された文字列を表示するクライアントを作成してみます。

ネットワークプログラミングの関数の流れ

 socket 関数は、ネットワーク上でデータをやりとりする時に必要な領域の確保を行います。
 socket 関数で取得した領域は、close 関数で開放できます。
 サーバのbind, listen, accept 関数は、セットで、クライアントからの受信を可能にします。
 クライアントのconnect 関数によって、セッションが確立し、データの送受信が可能となります。
 終了時は、shutdown 関数を、サーバとクライアントの両方から発行することで終了します。

クライアントAP     サーバAP
 (hellocl)          (hellosv)

                   socket sid1
                   bind sid1
                   listen
                   accept sid2
socket sid
connect sid    →
.....
                   recv sid
send sid2      →
.....
recv sid
               ←  send sid2
.....
shutdown sid   →
               ←  shutdown sid2
close sid          close sid2
                   close sid1

ネットワークプログラムのソース

 Hello サーバという、クライアントから接続されると "Hello world." を出力するサーバのソース(hellosv.c, hellosv.pl)と、Hello サーバに接続し出力された文字列を表示するクライアントのソース(hellocl.c, hellocl.pl)です。
 C言語版は、make コマンドにより、メイクすることができます。

プログラムの種類 C言語版 Perl版 telnet
サーバプログラム hellosv.c hellosv.pl  
クライアントプログラム hellocl.c hellocl.pl telnet ホスト名 5001
メイクファイル makefile    

プログラムの実行方法

 サーバで、Hello サーバを起動した後、クライアントから接続すると、何回でも、Hello world. を表示します。
 サーバプログラムは、delキーや、Ctrl+Cなどで終了します。
 Perl版のプログラムは、拡張子に.plが付きます。
 クライアントプログラムの代わりに、標準のtelnetコマンドを使うこともできます。
 サーバとクライアントのプログラムの組み合わせは自由です。

サーバとクライアントにそれぞれのプログラムを転送
srv01# rcp hellocl srv02:.

サーバプログラムの起動
srv01# hellosv srv01

クライアントプログラムの起動
srv02# hellocl srv01
Hello world.

クライアントにtelnetプログラムを利用
srv02# telnet srv01 5001
Trying 10.0.1.1...
Connected to srv01.
Escape character is '^]'.
Hello world.
Connection closed by foreign host.

通信データのダンプ

 実際に、ネットワークを流れるデータを見てみましょう。
 セッションの接続から、"Hello world."のデータ送信の状況を見てみます。
 通信データのダンプには、tcpdump などのツールを使用します。

通信データのフォーマット

 通信データには、TCPヘッダ、IPヘッダ、イーサネットヘッダが付加されます。
 IPヘッダにはIPアドレスなどの情報があり、通信相手のホストを識別します。
 また、TCPヘッダには、ポート番号などの情報があり、通神相手のプログラムを識別します。

 通信データのフォーマットは、以下のような内容です。

[         Ether header (14)             ] [   -
-         IP header (20)                      -
-   ] [   TCP header (20)                     -
-               ] [  data   ]

[ to MAC addr   ] [ from MAC addr ] [typ] Vh Ts
[siz] [flagment ] Tl Pn [sum] [ to addr ] [from
addr] [toP] [frP] [ SEQ no  ] [ ACK no  ] Of Fg
[wsz] [sum] [ugp] [ option  ] [dat]

00 00 4c 11 99 75 00 00 4c 11 c4 30 08 00 45 00 
00 2c 81 b2 00 00 1e 06 d1 dc 85 d0 1e c9 85 d0 
1e d4 09 f8 13 89 60 a1 4e 01 00 00 00 00 60 02 
40 00 44 79 00 00 02 04 04 00 82 4c 

通信データの各ヘッダ情報

 通信データの各ヘッダ情報の内容は、以下のような内容が格納されています。

===イーサネットヘッダ情報===
MAC address[5]: MACアドレス
  00004c119975: ハードウェアメーカ毎に設定
  00004c11c430: ハードウェアメーカ毎に設定
Ethernet type[2]: イーサネットタイプ
  0800: IP
  0806: ARP

===IPヘッダ情報===
IP Version / Header size[1]: IPバージョン/ヘッダサイズ
  4: バージョン4
  5: 20byte (5*4)
TOS (type of service)[1]: サービス種別
  00:
Total IP size[2]: IPパケットのトータル長
  002c: 44byte (0x2c)
Flagment[4]: IPパケット分割情報
  81b20000:
TTL (time of live)[1]: IPパケットの寿命
  1e: 30秒 (0x1e)
Protocol number[1]: IPプロトコル番号
  01: ICMP
  06: TCP
  11: UDP
Check sum[2]: IPヘッダのチェックサム
  d1dc:
IP address[4]: IPアドレス
  85d01ed4: srv01(例の場合)
  85d01ec9: srv02(例の場合)

===TCPへッダ情報===
Prot no[2]: ポート番号
  0014: port 20 (ftp-data)
  0015: port 21 (ftp)
  0017: port 23 (telnet)
  0050: port 80 (http)
  09f8: port 2552 (例の場合:サーバ->クライアント)
  1389: port 5001 (例の場合:クライアント->サーバ)
SEQ no[4]: シーケンス番号
  60a14e01:
ACK no[4]: 応答確認番号
  00000000:
Offset[1]: データオフセット
  6: 24byte (6*4)
  0:
Flag[1]: フラグ
  01: FIN フィンビット (FINish)
    TCPコネクションのshutdown時、切断を要求
  02: SYN シンクロビット (SYNc)
    TCPコネクションのconnect時、最初のパケットに付加
  04: RST リセットビット(ReSeT)
    データ転送のキャンセルなど、コネクションの強制切断を要求
  08: PSH プッシュビット (PuSH)
    データ通信時バッファリングせずに転送
  10: ACK 応答ビット(ACKnowledge)
    ほとんどのパケットに付加される応答確認フラグ
  20: URG 緊急ビット(URGent)

通信データの流れ

 通信データのパケットの種類と、TCP ソケット状態の遷移と通信データの流れの関係です。
 TCP/IPでは、コネクションを確立するために、SYNフラグ付きのパケットを送り、ACK SYNフラグ付きのパケットを受け取り、ACKフラグ付きのパケットを送ります。このように、フラグ付きのデータを3回やりとりするため、3WAYハンドシェイクと呼んでいます。

クライアントAP     サーバAP
 (hellocl)          (hellosv)

                   socket sid1
                   bind sid1
                   listen
                   [LISTEN]
                   accept sid2
socket sid
connect sid    →SYN
[SYN_SENT]
        ACK SYN←
                   [SYN_RECEIVED]
               →ACK
[ESTABLISHD]       [ESTABLISHD]
.....
                   recv sid2
send sid       →ACK PUSH
            ACK←
.....
recv sid
       ACK PUSH←  send sid2
               →ACK
.....
shutdown sid   →FIN
[CLOSE_WAIT]       [FIN_WAIT_1]
        ACK FIN←  shutdown sid2
                   [FIN_WAIT_2]
               →ACK
[LAST_ACK]         [TIME_WAIT]
close sid          close sid2
                   close sid1

TCP ソケット状態

 TCP ソケットの状態には次のようなものがあります。
 netstat コマンドで、TCP ソケットの状態を参照することができます。 セッションが確立している場合は、ESTABLISHEDと表示されます。



Copyright (C)1995-2002 ASH multimedia lab.
mail : info@ash.jp