情報処理 iib(n) vol.4

66
情情情情 情情情情 IIb(n) vol.4 IIb(n) vol.4 情情情情情情 情情情

Upload: elata

Post on 14-Jan-2016

50 views

Category:

Documents


0 download

DESCRIPTION

情報処理 IIb(n) vol.4. 慶應義塾大学 村井純. 今日やること. コンピュータコミュニケーションの基礎 トランスポート層 TCP 輻輳制御 状態遷移 コンピュータコミュニケーションのモデル プロキシサーバ. TCP (Transmission Control Protocol). 異なるホストのアプリケーション間に信頼性のある通信を提供 IP が提供する通信に信頼性を与える コネクション型通信 タイムアウトと再転送 エラー検出とエラー訂正 フロー制御 順序の再構成 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 情報処理 IIb(n) vol.4

情報処理情報処理 IIb(n) vol.4IIb(n) vol.4

慶應義塾大学村井純

Page 2: 情報処理 IIb(n) vol.4

今日やること今日やること

コンピュータコミュニケーションの基礎–トランスポート層• TCP

– 輻輳制御– 状態遷移

コンピュータコミュニケーションのモデル–プロキシサーバ

Page 3: 情報処理 IIb(n) vol.4

TCP TCP (Transmission Control Protocol)(Transmission Control Protocol)

異なるホストのアプリケーション間に信頼性のある通信を提供

IP が提供する通信に信頼性を与える•コネクション型通信•タイムアウトと再転送•エラー検出とエラー訂正•フロー制御•順序の再構成

– データ転送に関するインターフェイスを提供

Page 4: 情報処理 IIb(n) vol.4

輻輳制御ルール1:返事で判断輻輳制御ルール1:返事で判断

返事が早い→空いてる→沢山送る返事が早い→空いてる→沢山送る

Page 5: 情報処理 IIb(n) vol.4

輻輳制御ルール輻輳制御ルール 22 :混んだら小さく:混んだら小さく

返事が遅い→混んでる→少し送る返事が遅い→混んでる→少し送る

Page 6: 情報処理 IIb(n) vol.4

輻輳制御ルール輻輳制御ルール 22 :混んだら小さく:混んだら小さく

返事が無い→混んでる→少し送る返事が無い→混んでる→少し送る

Page 7: 情報処理 IIb(n) vol.4

輻輳制御ルール輻輳制御ルール 33 :空いても急ぐな:空いても急ぐな

返事が早い→空いてる→ゆっくり送る返事が早い→空いてる→ゆっくり送る

Page 8: 情報処理 IIb(n) vol.4

サンフランシスコ→藤沢(バイト数サンフランシスコ→藤沢(バイト数 //日)日) TCP/UDPTCP/UDP 利用別グラフ利用別グラフ

02000000000400000000060000000008000000000100000000001200000000014000000000

1 2 3 4 5 6 7

/バ

イト

数日

UDPTCP

Page 9: 情報処理 IIb(n) vol.4

インターネットが遅い原因インターネットが遅い原因 返事が遅い–相手がのろい–途中がのろい

相手がのろい場合–相手が過負荷• アクセスが多すぎる• 力がなさ過ぎる

途中がのろい場合–どこかの待ち行列であふれている

Page 10: 情報処理 IIb(n) vol.4

TCPTCP ヘッダヘッダ

Src PortSrc Port Dst PortDst Port

Sequence NumberSequence Number

Acknowledgement NumberAcknowledgement Number

OffsetOffset ReservedReserved FlagFlag Window SizeWindow Size

TCP ChecksumTCP Checksum Urgent PointerUrgent Pointer

Option (if any)Option (if any) PaddingPadding

DataData

Page 11: 情報処理 IIb(n) vol.4

Flags CODEFlags CODE

Flags は TCP がコネクション制御に利用 6 つの flags がある

– URG : Urgent Pointer が有効– ACK : Acknowledge Number が有効– PSH : セグメントをすぐに上位層へ渡す– RST : エラーによる強制的なクローズ– SYN : コネクションセットアップの同期をとる– FIN : コネクションを終了する

Page 12: 情報処理 IIb(n) vol.4

TCPTCP の状態遷移図の状態遷移図

SYN_SENT

ESTABLISHED

CLOSED

LISTEN

SYN_RCVD

Passive OpenActive Open

Send SYNRecv SYN

send SYN,ACK Send SYN

Recv SYN

Recv ACK Recv SYN,ACKSend ACK

Recv RST

データ転送状態

Page 13: 情報処理 IIb(n) vol.4

コネクション開始コネクション開始

送信側送信側 受信側受信側

SEQ=123SEQ=123

SEQ=123SEQ=123

ACK=813ACK=813

SEQ=812SEQ=812

SEQ=813SEQ=813ACK=124ACK=124

SYN SEQ=812SYN SEQ=812 No ACKNo ACK

SYN SEQ=123 ACK=813SYN SEQ=123 ACK=813

SEQ=813 ACK=124SEQ=813 ACK=124

Page 14: 情報処理 IIb(n) vol.4

3way Handshake3way Handshake コネクションのセットアップ

– ホスト 1 、ホスト 2 間で•ホスト 1 は SYN Flag のついたパケットを送る•SYN を受けたホスト 2 は相手との同期を取るために

SYN Flag のついたパケットを送る。この時いっしょに受け取った SYN に対する ACK Flag もつける

•ホスト 2 から SYN を受け取ったホスト 1 は ACK を返す

– SYN と ACK が相乗り•Piggy Back

Page 15: 情報処理 IIb(n) vol.4

コネクションの終了コネクションの終了 コネクションの終了は FIN   Flag によって行う コネクションの終了は一方ごとにできる

FIN SEQ=457

SEQ=789 ACK=458

FIN SEQ=790

SEQ=458 ACK=791

Page 16: 情報処理 IIb(n) vol.4

データの転送データの転送 Sequence Number と Acknowledge Number によって、

データの順番を保証 ACK が帰ってきたら次のデータを送る ACK が帰ってこなかったら前のデータを再転送

SEQ=231 DATA

SEQ=456 ACK=232

SEQ=232 DATA

Page 17: 情報処理 IIb(n) vol.4

データ転送(続き)データ転送(続き)

いちいち ACK を待つと効率が悪い 推測を元にある程度先送りした方が良い だが、先送りしすぎると ACK がなかなか

帰ってこない 幅を決めなければならない

Page 18: 情報処理 IIb(n) vol.4

Congestion ControlCongestion Control(( 輻輳制御輻輳制御 ))

輻輳 (Congestion)–中間ノードがデータグラムの過負荷によっ

て遅延が生じた状態. 輻輳を解決するために–ウィンドウコントロール–スロースタート

Page 19: 情報処理 IIb(n) vol.4

ウィンドウコントロールウィンドウコントロール

先送りする幅を決める仕組み 送るパケットを制限する

44

ACK=335ACK=335

44

SEQ=238SEQ=238SEQ=270SEQ=270SEQ=302SEQ=302SEQ=334SEQ=334

Page 20: 情報処理 IIb(n) vol.4

スロー スタート・スロー スタート・ ネットワークに送り出されるパケットの通信速度を他方のエンドから返される確認応答の通信速度を同期させるためのもの

送り手の TCP に別のウィンドウを追加する。– 輻輳ウィンドウ (cwnd)

新しいコネクションが確立 輻輳ウィンドウをセグメント 1 つに初期化 ACK が受け取られるたびに、輻輳ウィンドウ

は 1 セグメントずつ増やされる

Page 21: 情報処理 IIb(n) vol.4

スロー・スタート スロー・スタート animationanimation

cwnd=1 12

cwnd=234

5cwnd=3

1:513(512)ack1, win4096

ack513, win8192

513:1025(512)ack1, win4096

1025:1537(512)ack1, win4096

ack1025, win8192

ack1537, win8192

1537:2049(512)ack1, win4096

2049:2561(512)ack1, win4096

cwnd=4ack2049, win8192 9cwnd=5

Page 22: 情報処理 IIb(n) vol.4

まとめまとめ

IP はホストホスト間の通信まで トランスポート層はポート番号によっ

てアプリケーション間の通信を実現 UDP は IP の提供する品質の通信 TCP はいろいろな機能を用いることで、

信頼性のある通信をアプリケーション間に提供する

Page 23: 情報処理 IIb(n) vol.4

代返代返

代わりに返事をすること– 授業

当事者がその場に入れないときに使う

クライアントがサーバに到達する代わり代理に問い合わせる

Proxy Server

Page 24: 情報処理 IIb(n) vol.4

Proxy ServerProxy Server 本物のサービスの代わりに、その代理

のサービスを提供するサーバ– WWW Proxy Server

Proxy

本物 server

Client

Page 25: 情報処理 IIb(n) vol.4

Socket Programming2Socket Programming2

慶応大学政策・メディア研究科今泉英明

[email protected]

Page 26: 情報処理 IIb(n) vol.4

先週の課題について先週の課題について

20人が提出 (49%)– 締め切りを過ぎても再提出可能(出さないよりは

大幅にまし ) 寄せられた問題点– バッファサイズが 1024bytesじゃ少ない。– void main() は int main() にした方がいい。– サーバのソケットから読み出すべき。– 他人の名前でメールできてしまう。– Subject が書けるようになっていない

Page 27: 情報処理 IIb(n) vol.4

課題の問題点課題の問題点

サーバとうまくおしゃべりできていない– Read() がブロックしてしまう– サーバからしゃべりだしたりしたとき– サーバから 1024bytes以上送られてきたとき– 以下の順序に依存しているのが原因1. 標準入力から読む (read() でブロック )

2. ソケットに書き込む3. ソケットから読む (read() でブロック )

4. 標準出力に書き込む

Page 28: 情報処理 IIb(n) vol.4

今日の目標今日の目標

ソケットプログラミングの基礎を学ぶ–非同期多重入出力• 複数のディスクリプタを同時に利用しよう!

– TCP を用いるサーバを書こう• UNIX プログラミングの勉強

– プロセスについて

Page 29: 情報処理 IIb(n) vol.4

非同期多重入出力非同期多重入出力

読み込み準備の整ったファイルディスクリプタから読みたい

書き込み準備の整ったファイルディスクリプタから読みたい

とにかく複数のディスクリプタから非同期に読み書きがしたい

Page 30: 情報処理 IIb(n) vol.4

Select()Select() システムコールシステムコール

複数のディスクリプタを非同期に扱うためのシステムコール–ファイルディスクリプタの集合を渡して、読み出し /書き込み可能なファイルディスクリプタを教えてもらう

–一定のタイムアウトも指定できる

Page 31: 情報処理 IIb(n) vol.4

fd_setfd_set ファイルディスクリプタの集合を保持するためのビットマップ 以下のような 10bit のビットマップにファイルディスクリプタ

0, 4, 8 という集合を表現させると

0 0 0 0 0 00 0 0 0

0 1 2 3 4 5 6 7 8 9

1 0 0 0 1 00 0 0 1

0 1 2 3 4 5 6 7 8 9

•FreeBSD3.2, Solaris 2.6 では 1024bits•BSD/OS3.1 では 256bits

10bits あると 10個のファイルディスクリプタの集合を表現することができる

Page 32: 情報処理 IIb(n) vol.4

fd_setfd_set の操作の操作 以下のインターフェースを利用して操作

fd_set fds;FD_ZERO(&fds); /*fds をゼロに初期化 */FD_SET(fd, &fds);      /*fds に fd 番目のビットを上げる */FD_ISSET(fd, &fds);     /*fds に fd 番目のビットが設定さ                 れているか調べる*/FD_CLR(fd, &fds);      /*fds から fd 番目の bit を落とす */

Page 33: 情報処理 IIb(n) vol.4

Select() Select() システムコールシステムコール int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

•Select は 0 から (nfds-1)までのファイルディスクリプタを検査-最大の値のディスクリプタ +1 を設定

・ readfds/writefds は読み込み /書き込み可能かを調べたいディスクリプタの集合・ exceptfds はとりあえず気にしない (詳しくは参考文献 21章 )・どれかのディスクリプタが読み /書き可能になった場合に戻る・それ以外はタイマの指定に依存・ timeout はタイムアウトするまでのタイマ値(秒、マイクロ秒)

Page 34: 情報処理 IIb(n) vol.4

timevaltimeval 構造体構造体

long である秒とマイクロ秒の二つのメンバ タイマの値を指定できる

long tv_sec

long tv_usec

Page 35: 情報処理 IIb(n) vol.4

タイマの設定タイマの設定

Select は以下の3つのタイマの指定が可能1. NULL を指定

- タイムアウトしない

2. Timeval 構造体を指定- 指定された一定時間でタイムアウト

3. 0秒 0マイクロ秒に指定した Timeval 構造体を指定

- ファイルディスクリプタを検査した後すぐにタイムアウト

Page 36: 情報処理 IIb(n) vol.4

SelectSelect の手順の手順 11ファイルディスクリプタ 0, 4, 8 という集合のうち

どれが読み出し可能になったか知りたい場合

0 0 0 0 0 00 0 0 0

0 1 2 3 4 5 6 7 8 9int nfds;fd_set fds;FD_ZERO(&fds);FD_SET(0, &fds);FD_SET(4, &fds);FD_SET(8, &fds);nfds = 8 + 1;select(nfds, &fds, NULL, NULL, NULL); 読み出し可能なビットが立つ

1 0 0 0 0 00 0 0 01 0 0 0 1 00 0 0 01 0 0 0 1 00 0 0 1

1 0 0 0 0 00 0 0 1

Page 37: 情報処理 IIb(n) vol.4

SelectSelect の手順の手順 22Select を実行した後の処理

0 1 2 3 4 5 6 7 8 9

select(nfds, &fds, NULL, NULL, NULL); 読み出し可能なビットが立つif(FD_ISSET(0, &fds){

read(0, ….);}if(FD_ISSET(4, &fds){

read(4, ….);}if(FD_ISSET(8, &fds){

read(8, …..);}

1 0 0 0 0 00 0 0 1

Page 38: 情報処理 IIb(n) vol.4

実際に変更実際に変更

別紙参照

Page 39: 情報処理 IIb(n) vol.4

ここまでのまとめここまでのまとめ ネットワークプログラミングをするにはソケッ

トを利用する ネットワークに流す複数バイトのデータ型( lon

g,short) はネットワークバイトオーダにあわせる

TCP でコネクションを張ると byte stream が流れるパイプが張れる– その上に流れるデータはそれを扱うプログラムが担

う 複数のディスクリプタを非同期に扱うには selec

t() システムコールを利用する。

Page 40: 情報処理 IIb(n) vol.4

サーバ側を書いてみようサーバ側を書いてみよう サーバも同様に TCP のコネクションが張れる

と単なるディスクリプタ 違いは、みんなからの接続要求を待つためのソケットを開く– 自分でソケットにアドレスを bind しなければなら

ない– 接続要求を保持するために Listen() を呼んでキュー

を作成– 要求に accept() して、それぞれのクライアントと

通信するためのディスクリプタを作成 あとは一緒

Page 41: 情報処理 IIb(n) vol.4

システムコールの流れシステムコールの流れ

socket()

connect()

write()

read()

close()

TCP クライアント TCP サーバ

read()

write()

close()

read()EOF の通知

socket()

bind()listen()

accept()

Page 42: 情報処理 IIb(n) vol.4

プログラムの流れプログラムの流れ

1. Sockaddr_in 構造体に、サーバの IP アドレスとポート番号を設定

2. ソケットを開く3. 1のアドレスをソケットに bind()

4. Listen(接続待機 ) でキューを作成5. 接続要求に対して Accept()

6. おしゃべり7. Close()

Page 43: 情報処理 IIb(n) vol.4

初期状態初期状態

クライアントプロセス

ホスト A

サーバプロセス

ホスト B

Port B

IP Address: xx.xx.xx.xx.IP Address: xx.xx.xx.xx.

Port C

Port A

Page 44: 情報処理 IIb(n) vol.4

SocketSocket を開いた状態を開いた状態

クライアントプロセス

ホスト A

サーバプロセス

ホスト B

Port B

IP Address: xx.xx.xx.xx.IP Address: xx.xx.xx.xx.

Port C

Port A

Socket を開く

Page 45: 情報処理 IIb(n) vol.4

bindbind した状態した状態

クライアントプロセス

ホスト A

サーバプロセス

ホスト B

Port B

IP Address: xx.xx.xx.xx.IP Address: xx.xx.xx.xx.

Port C

Port A

Proto LocalAdddress ForeignAddress StateTCP *.A *.* Closed

Page 46: 情報処理 IIb(n) vol.4

Listen()Listen()

クライアントプロセス

ホスト A

サーバプロセス

ホスト B

Port B

IP Address: xx.xx.xx.xx.IP Address: xx.xx.xx.xx.

Port C

Port A

Proto LocalAdddress ForeignAddress StateTCP *.A *.* Listen

Page 47: 情報処理 IIb(n) vol.4

Listen()Listen()拡大拡大

サーバプロセス

ホスト B

Port B

IP Address: xx.xx.xx.xx.

Port C

Port A

Proto LocalAdddress ForeignAddress StateTCP *.A *.* Listen

3Way Hand Shake を済ました接続要求や SYN を保持するためのキュー

Page 48: 情報処理 IIb(n) vol.4

クライアントがクライアントが Connect()Connect()

クライアントプロセス

ホスト A

サーバプロセス

ホスト B

Port B

IP Address: xx.xx.xx.xx.IP Address: yy.yy.yy.yy

Port C

Port APort X

Connect()

Proto LocalAdddress ForeignAddress StateTCP *.A *.* SYN_RCVD

SYN

Page 49: 情報処理 IIb(n) vol.4

キューの拡大キューの拡大

サーバプロセス

ホスト B

Port B

IP Address: xx.xx.xx.xx.

Port C

Port A

Proto LocalAdddress ForeignAddress StateTCP *.A *.* SYN_RCVD

3Way Hand Shake を済ました接続要求や SYN を accept されるまで保持するためのキュー

埋まり空き

Page 50: 情報処理 IIb(n) vol.4

Accept()Accept()

クライアントプロセス

ホスト A

サーバプロセス

ホスト B

Port B

IP Address: xx.xx.xx.xx.IP Address: yy.yy.yy.yy

Port C

Port APort X

Connect()

Proto LocalAdddress ForeignAddress StateTCP *.A *.* ListenTCP xx.xx.xx.xx.A yy.yy.yy.yy.X Establish

Page 51: 情報処理 IIb(n) vol.4

新しいシステムコール新しいシステムコール

bind() listen() accept()

Page 52: 情報処理 IIb(n) vol.4

bind() bind()

int bind(int s, struct sockaddr *name, int namelen);– ソケットに名前 ( アドレス ) を付ける– アドレスに INADDR_ANY を指定した場合は、自分の持つすべてのアドレスに対しての要求を受け付ける• *.port-number• そのサービスを提供するアドレスを制限できる

– 開いたソケットのステートは closed

Page 53: 情報処理 IIb(n) vol.4

同じポート番号を利用する同じポート番号を利用する2つのサーバ2つのサーバ

あるホスト A は xx.xx.xx.xx と yy.yy.yy.yy の二つのアドレスを持つ– サーバ A のソケットを xx.xx.xx.xx, port 10001 に bind– サーバ B のソケットを yy.yy.yy.yy, port 10001 に bind– サーバ C のソケットを INADDR_ANY, port 12345 に bind

socket の状態はProto LocalAdddress ForeignAddress StateTCP xx.xx.xx.xx.10001 *.* closedTCP yy.yy.yy.yy.10001 *.* closedTCP *.12345 *.* closed

port 10001 へのクライアントの要求は、目的アドレスによって、異なるサーバが答えることになる

Page 54: 情報処理 IIb(n) vol.4

絵にすると、、、絵にすると、、、

サーバ A

ホスト B

Port B

Address: xx.xx.xx.xx.

Port C

Port A

アドレス毎に独立したポート表を持つ

サーバ B Port B

Port C

Port A

Address: zz.zz.zz.zzサーバ C

Page 55: 情報処理 IIb(n) vol.4

listen()listen()

int listen(int s, int backlog);– s は ソケットディスクリプタ– backlog はキューの長さ (backlog分の要求を保持できる )• 接続要求は、 accept ()されるまで backlog長のキューに保持される• キューがあふれると、その要求は無視

Page 56: 情報処理 IIb(n) vol.4

キューの拡大キューの拡大

サーバプロセス

ホスト B

Port B

IP Address: xx.xx.xx.xx.

Port C

Port A

Proto LocalAdddress ForeignAddress StateTCP *.A *.* SYN_RCVD

backlog=4 のキュー

埋まり空き

Page 57: 情報処理 IIb(n) vol.4

accept()accept()

int accept(int s, struct sockaddr *client, int *namelen)– キューで待っている接続要求を取り出して、その

クライアントと通信するためのディスクリプタを作成して、返す

– client にはクライアントの socket のアドレス、namelen には client のサイズ

Page 58: 情報処理 IIb(n) vol.4

Accept()Accept()

クライアントプロセス

ホスト A

サーバプロセス

ホスト B

Port B

IP Address: xx.xx.xx.xx.IP Address: yy.yy.yy.yy

Port C

Port APort X

Connect()

Proto LocalAdddress ForeignAddress StateTCP *.A *.* ListenTCP xx.xx.xx.xx.A yy.yy.yy.yy.X Establish

Page 59: 情報処理 IIb(n) vol.4

accept()accept() の後の後 accept() で返ってきたファイルディスク

リプタを利用してクライアントとしゃべる

要求待機用のソケットも select で扱える– listen している socket が読み込み可能なと

きは accept可能なとき select をもちいることで、多くのクライ

アントの要求に答えることができる

Page 60: 情報処理 IIb(n) vol.4

サーバの気持ちになってみよサーバの気持ちになってみようう

そんなたくさんのソケットを扱ったり、めんどくさいことはしたくない

沢山のクライアントが接続してきたら、もう大変

猫の手も借りたいわ!

Page 61: 情報処理 IIb(n) vol.4

えーい、クローンだ。えーい、クローンだ。

fork システムコール– int fork();–自分とまったく同じ複製プロセスを作るシ

ステムコール– 0 が帰ってきたら自分は子プロセス–正の整数が帰ってきたら自分は fork() を呼び出した親プロセス

– -1 は失敗

Page 62: 情報処理 IIb(n) vol.4

処理の流れ処理の流れ

接続要求があったら、 accept して , とりあえず fork();–子プロセスだったら、サービスの提供開始–親プロセスだったら、接続要求待ち

Page 63: 情報処理 IIb(n) vol.4

シグナルシグナル

は来週

Page 64: 情報処理 IIb(n) vol.4

まとめまとめ

TCP サーバのプログラムは、– Socket を開く– socket にアドレス (Ipaddress, port 番号 ) を bin

d– listen() でキューを作成– accept() でそれぞれのクライアントへのディス

クリプタを作成– おしゃべり– 最後に close()

Page 65: 情報処理 IIb(n) vol.4

今週の課題今週の課題 fork() を利用せずに、 select() のみを

利用して、 echo サーバを作りなさい。– listen のディスクリプタも accept() でも

らったディスクリプタも select で非同期多重

– C の勉強なので、がんばってね。–完全でなくても出してください。

Page 66: 情報処理 IIb(n) vol.4

締め切り締め切り

10 月 25 日午後11時59分59秒 いつもどおり SOI のシステムで提出