TCP

情報処理IIb(n) vol.3
慶應義塾大学
村井純
今日やること

コンピュータコミュニケーションの基礎
– 先週の続き
• DNS
• ネットワーク層まとめ、ここまでの復習
– トランスポート層
• UDP/TCP
• コネクション型、コネクションレス型

コンピュータコミュニケーションのモデル
– プロキシサーバ
名前とIPアドレス

コンピュータは数字を扱う方が得意
– コンピュータはアドレスが分ればOK

人間は数字を扱うのは得意ではない
– 数字より名前の方が扱いやすい

名前
– ホストの名前 (例: mail0 )
– 組織の名前 (例: sfc.keio.ac.jp)
ドメインの構造
jp
ad
wide
edu
ac
keio
sfc
keio
jaist
mag
cs
stanford
leland
sr
コマンドで名前を引いてみよう


nslookupコマンド
Name serverに聞いて、名前からIPアドレ
スを調べるコマンド
% nslookup racerx.sfc.wide.ad.jp
Server: ns0.sfc.keio.ac.jp
Address: 133.27.4.121
Name:
racerx.sfc.wide.ad.jp
Address: 203.178.139.177
ネットワーク層のまとめ

ホスト・ホスト間の通信を担う
– ルーティング
– フォワーディング
– フラグメント・リアセンブル

信頼性のある通信を行うことはできない。
– 転送されるデータ(パケット)はなくなってしまう可能性
がある
– 落としたら、報告だけする

信頼性は上位層で。。
ちょっぴりここまでの復習
Application
TCP
IP
Network
Interface
Physical
ホスト間の通信を実現
相互接続されたホスト間の通信を実現
物理的な通信状態の実現
ネットワーク層まで利用することで、インターネット上の
ホストホスト間の信頼性のない通信を実現
OSI参照7層モデル
各メーカーの機器が相互接続出来ない。
統合標準化するための体系するための考案
プロトコル設計の物差し
Application
Application
Presentation
Presentation
Session
Session
Transport
Transport
Network
Network
Network
Datalink
Datalink
Datalink
Physical
Physical
Physical
OSI参照7層モデル
各メーカーの機器が相互接続出来ない。
統合標準化するための体系するための考案
プロトコル設計の物差し
Application
Application
Application
Application
Presentation
Presentation
Presentation
Presentation
Session
Session
Session
Session
Transport
Transport
Transport
Transport
Network
Network
Network
Network
Datalink
Datalink
Datalink
Datalink
Physical
Physical
Physical
Physical
インターネットの階層モデル



IP層はバケツリレー(伝言ゲーム)
IP層ではじめてエンドエンドの通信が確立
IPの上位層はIPの機能をするために世界中のホストと通
信できる
Application
Application
Application
Application
TCP
TCP
TCP
TCP
IP
IP
IP
IP
Network
Interface
Network
Interface
Network
Interface
Network
Interface
Physical
Physical
Physical
Physical
トランスポート層

アプリケーション間(プロセス間)の通信を
担う
– アプリケーションの識別にはポート番号と呼ば
れる16bitの数字を用いる
– ネットワーク層はホスト間の通信

TCP・UDP
– TCP/UDP毎に独立したポートの表を持つ
アプリケーションとポート
IPアドレス(ホスト)と上位プロトコル、ポートによって
通信を一意に識別
ブラウザ
ホストA.12345とホストB.80の通信
12345
WWW
サーバ
80
TCP
TCP
TCP
TCP
IP
IP
IP
IP
Network
Interface
Network
Interface
Network
Interface
Network
Interface
Physical
Physical
Physical
Physical
ホストA
ホストB
WellKnown Port

1024以下のポート番号は以下のようなサービス
のために予約されている
–
–
–
–
–
–
–
/etc/servicesに登録されている
Echo 7/tcp
Echo 7/udp
ftp
21/tcp
Ssh 22/tcp
telnet 23/tcp
http 80/tcp
/etc/services
#
# @(#)services 1.16 90/01/03 SMI
tcpmux
1/tcp
# rfc-1078
echo
7/tcp
echo
7/udp
discard
9/tcp
sink null
discard
9/udp
sink null
systat
11/tcp
users
daytime
13/tcp
daytime
13/udp
netstat
15/tcp
chargen
19/tcp
ttytst source
chargen
19/udp
ttytst source
ftp-data
20/tcp
ftp
21/tcp
telnet
23/tcp
smtp
25/tcp
mail
time
37/tcp
timserver
time
37/udp
timserver
ポート番号の例
www.sfc.wide.ad.jpのport 番号80番に接続
[kenken@bono]telnet www.sfc.wide.ad.jp 80
Trying 203.178.140.3 ...
Connected to enterprise.sfc.wide.ad.jp.
Escape character is '^]'.
GET /index.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<TITLE>Tokuda, Murai, Kusumoto &amp; Nakamura Laboratory</TITLE>
<LINK REV=MADE HREF="mailto:[email protected]">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO2022-JP">
</HEAD>
<BODY BGCOLOR="#D6AF85">
WWWを見る
GET /index.html
送りたいデータ
IP層で決まった次に渡すべきホスト(nexthop)の物理アドレス
宛先IPアドレスと送り元IPアドレスなどをヘッダに書き込む。
宛先IPアドレスから自分宛てでないと判断する
IPヘッダの宛先アドレスが自分であることを知る。
受け取ったパケットのヘッダをのぞき、自分宛てか確認
ヘッダに宛先ポート番号、送り元ポート番号などを書いて
と自分の物理アドレスと上位のプロトコルをヘッダに書き込む。
と自分の物理アドレスと上位のプロトコルをヘッダに書き込む。
ルーティングテーブルから最終的な宛先IPアドレスへは
ブラウザが相手のアドレスとポートを指定しデータを
TCPヘッダに書いある宛先ポート番号が80であることを
80番のポートにbindされたhttpサーバーがTCP層から
IPヘッダに書いてある上位層を調べ、TCP層であると知る
ヘッダから上位層をIPと判断し、ヘッダを取り除いてIP層へ
物理的に伝達される
付け、IP層へ渡す
トレーラーを付けるネットワークインターフェースもある。
トレーラーを付けるネットワークインターフェースもある。
どの直接繋がったホストへ渡せばよいか判断してその
TCP層に渡す
知る。80番にbindされているプロセスに渡す
データを受け取る。
物理的に伝達される
TCP層へ渡す。
渡す
そのパケットを物理メディアに流す
そのパケットを物理メディアに流す
インターフェースのネットワークインターフェース層へ渡す
Application
Application
Application
Application
data
data
TCP
data
IP
data
Network
data
Interface
Physical data
TCP
IP
data
Network
data
data
Interface
Physical
TCP
IP
data
Network
data
Interface data
data Physical
TCP
data
IP
data
Network
data
Interface
dataPhysical
TCP vs UDP
ネットワークを利用するアプリケーションは主に
トランスポートプロトコルとしてTCPとUDPを利用する。
TCP
•Reliable
•Sequence Control
•Flow Control
•Congestion Control
•Retransmission
•Bit-based charging
UDP
•Unreliable
•No Sequence Control
•No Flow Control
•No Congestion Control
•No Retransmission
•Fixed-rate charging
コネクション型通信

2地点間を仮想回線(Virtual Circuit)で結
ぶ
中継
A
B
コネクションレス型通信

2地点間をデータグラム転送で結ぶ
中継
A
B
向き・不向き
Virtual-circuit
長所
信頼性がある
オーバヘッドが大きい
短所 高い処理能力が必要
Datagram
オーバーヘッドが
小さい
高い処理能力を必
要としない
信頼性がない
UDP
(User Datagram Protocol)

機能的にはIPと同じ
– 信頼性のないコネクションレス型通信をアプリケー
ションに提供

パケットフォーマット
31
1516
0
発信元ポート番号
発信先ポート番号
UDPデータ長
UDPチェックサム
データ
TCP
(Transmission Control Protocol)


異なるホストのアプリケーション間に信頼性の
ある通信を提供
IPが提供する通信に信頼性を与える
•
•
•
•
•
コネクション型通信
タイムアウトと再転送
エラー検出とエラー訂正
フロー制御
順序の再構成
– データ転送に関するインターフェイスを提供
輻輳制御ルール1:返事で判断
返事が早い→空いてる→沢山送る
輻輳制御ルール2:混んだら小さく
返事が遅い→混んでる→少し送る
輻輳制御ルール2:混んだら小さく
返事が無い→混んでる→少し送る
輻輳制御ルール3:空いても急ぐな
返事が早い→空いてる→ゆっくり送る
バイト数/日
サンフランシスコ→藤沢(バイト数/日)
TCP/UDP利用別グラフ
14000000000
12000000000
10000000000
8000000000
6000000000
4000000000
2000000000
0
UDP
TCP
1
2
3
4 5
月
6
7
インターネットが遅い原因

返事が遅い
– 相手がのろい
– 途中がのろい

相手がのろい場合
– 相手が過負荷
• アクセスが多すぎる
• 力がなさ過ぎる

途中がのろい場合
– どこかの待ち行列であふれている
TCPヘッダ
Src Port
Dst Port
Sequence Number
Acknowledgement Number
Offset
Reserved
Flag
TCP Checksum
Option (if any)
Data
Window Size
Urgent Pointer
Padding
Flags CODE


FlagsはTCPがコネクション制御に利用
6つのflagsがある
–
–
–
–
–
–
URG: Urgent Pointerが有効
ACK: Acknowledge Numberが有効
PSH: セグメントをすぐに上位層へ渡す
RST: エラーによる強制的なクローズ
SYN: コネクションセットアップの同期をとる
FIN: コネクションを終了する
TCPの状態遷移図
CLOSED
Passive Open
Recv SYN
send SYN,ACK
SYN_RCVD
Active Open
LISTEN
Send SYN
Recv RST
Send SYN
SYN_SENT
Recv SYN
Recv SYN,ACK
Send ACK
Recv ACK
ESTABLISHED
データ転送状態
コネクション開始
送信側
SEQ=812
受信側
SYN SEQ=812 No ACK
SEQ=123
SYN SEQ=123 ACK=813
SEQ=813
ACK=124
SEQ=123
SEQ=813 ACK=124
ACK=813
3way Handshake

コネクションのセットアップ
– ホスト1、ホスト2間で
• ホスト1はSYN Flagのついたパケットを送る
• SYNを受けたホスト2は相手との同期を取るために
SYN Flagのついたパケットを送る。この時いっしょ
に受け取ったSYNに対するACK Flagもつける
• ホスト2からSYNを受け取ったホスト1はACKを返す
– SYN と ACKが相乗り
• Piggy Back
コネクションの終了


コネクションの終了はFIN Flagによって行う
コネクションの終了は一方ごとにできる
FIN SEQ=457
SEQ=789 ACK=458
FIN SEQ=790
SEQ=458 ACK=791
データの転送



Sequence NumberとAcknowledge Numberによって、デー
タの順番を保証
ACKが帰ってきたら次のデータを送る
ACKが帰ってこなかったら前のデータを再転送
SEQ=231 DATA
SEQ=456 ACK=232
SEQ=232 DATA
データ転送(続き)




いちいちACKを待つと効率が悪い
推測を元にある程度先送りした方が良い
だが、先送りしすぎるとACKがなかなか帰ってこ
ない
幅を決めなければならない
Congestion Control(輻輳制御)

輻輳(Congestion)
– 中間ノードがデータグラムの過負荷によって
遅延が生じた状態.

輻輳を解決するために
– ウィンドウコントロール
– スロースタート
ウィンドウコントロール


4
先送りする幅を決める仕組み
送るパケットを制限する
SEQ=238
SEQ=270
SEQ=302
SEQ=334
ACK=335
4
スロー・スタート





ネットワークに送り出されるパケットの通信速度を
他方のエンドから返される確認応答の通信速度
を同期させるためのもの
送り手のTCPに別のウィンドウを追加する。
– 輻輳ウィンドウ(cwnd)
新しいコネクションが確立
輻輳ウィンドウをセグメント1つに初期化
ACKが受け取られるたびに、輻輳ウィンドウは1セ
グメントずつ増やされる
スロー・スタート animation
cwnd=1
1:513(512)ack1, win4096
1
ack513, win8192
cwnd=2
3
4
cwnd=3
6
7
cwnd=4
cwnd=5
2
513:1025(512)ack1, win4096
1025:1537(512)ack1, win4096
ack1025, win8192
1537:2049(512)ack1, win4096
5
2049:2561(512)ack1, win4096
ack1537, win8192
8
ack2049, win8192
9
まとめ




IPはホストホスト間の通信まで
トランスポート層はポート番号によってアプ
リケーション間の通信を実現
UDPはIPの提供する品質の通信
TCPはいろいろな機能を用いることで、信
頼性のある通信をアプリケーション間に提
供する
続Socket Programming1
慶応大学政策・メディア研究科
今泉英明
[email protected]
今日の目標

ソケットプログラミングの基礎を学ぶ
– TCPクライアントプログラムを通して説明
• 名前からIPアドレスを調べる
• Socketを開いてサーバとおしゃべりできるようにな
る

人間ブラウザ/人間メーラになる
ソケット(Socket)
Socketとはプロセス間通信(Inter Process
communication)を行うひとつの手段(API)であ
る
– ネットワークサーバ・クライアントプログラム
– 同一システム内のプロセス間通信
– 新たなトランスポート層の開発
などができる

プログラムの流れ
1.
2.
3.
4.
5.
6.
ホスト名からIPアドレスを取得
Sockaddr_in構造体に、サーバのIPアド
レスとポート番号を設定
ソケットを開く
2の構造体を使って、サーバと接続
おしゃべり
Close()
sockaddr_in構造体

ソケットのアドレスを記述するもの
– IPアドレス
– ポート番号
– プロトコルfamily
78
0
長さ
1516
31
proto
Port番号
IPアドレス
unused
unused
gethostbyname()関数



struct hostent *gethostbyname(const
char *name);
Nameで指定された名前を調べるための
関数
余裕のある人は/usr/include/netdb.hを
のぞいて、hostent構造体を調べてみよ
う!
ネットワーク・バイト・オーダ



注意
Network Byte Order
CPUアーキテクチャによって、バイトの並びが違う
– 一般にBig Endian(sparc等)とLittle Endian(Intel等)の二つ

ネットワーク上に流すバイト順を統一しなくてはならない
– Big Endianに統一

htons()/htonl()/ntohs()/ntohl()を利用
リトルエンディアン
ビッグエンディアン
16ビット整数
(short)
32ビット整数
(long)
1 2
1 2 3 4
2 1
4 3 2 1
システムコールの流れ
TCPクライアント
socket()
TCPサーバ
サーバ初期処理
connect()
write()
read()
read()
write()
close()
EOFの通知
read()
close()
初期状態
接続待機状態(Listen)
クライアント
プロセス
Port A
サーバ
プロセス
Port B
Port C
ホストA
IP Address: xx.xx.xx.xx.
ホストB
IP Address: xx.xx.xx.xx.
SocketをOpen
接続待機状態(Listen)
クライアント
プロセス
Port A
サーバ
プロセス
Port B
Port C
ホストA
IP Address: xx.xx.xx.xx.
ホストB
IP Address: xx.xx.xx.xx.
サーバと接続
サーバのIPアドレスとポート番号を指定して
Connect()
通信確立状態(Establish)
クライアント
プロセス
Port X
Port A
サーバ
プロセス
Port B
Port C
ホストA
IP Address: yy.yy.yy.yy
ホストB
IP Address: xx.xx.xx.xx.
サーバ通信
•ソケットディスクリプタを読み書きするだけ
•単なるバイトの列が通るだけ。
•IPアドレスもポート番号も気にする必要はない
•サーバとクライアント同士が通信するためのプ
ロトコル
クライアント
プロセス
GET /index.html
<TITLE>Title</TITLE>
<BODY>…………
サーバ
プロセス
低レベル入出力

ファイル操作
– 主に以下のシステムコールが基本
•
•
•
•
Open
Close
Read
Write
ファイルディスクリプタを開く
ファイルディスクリプタを閉じる
ファイルの内容を読む
ファイルに、書き込む
– Read/writeはファイルディスクリプタに対して
行われる
ネットワークプログラミング

ソケットディスクリプタに対して操作が行わ
れる
– Socket
– Close
– Read
– Write
む
ソケットディスクリプタを開く
ソケットディスクリプタを閉じる
ソケットからバイト列を読み出す
ソケットに対してバイト列を書き込
socket()システムコール

int socket(int family, int type, int
proto);
– familyにはプロトコルファミリを指定
•
•
•
•
AF_INET
AF_INET6
AF_LOCAL
AF_ROUTE
IPv4プロトコル
IPv6プロトコル
UNIX Domain Socket
経路制御ソケット
– Typeにはソケットのタイプ(以下のどれか)
• SOCK_STREAM
• SOCK_DGRAM
• SOCK_RAW
ストリームソケット
データグラムソケット
rawソケット
– Protoにはrawソケット以外、通常0
socket()システムコール


成功: ソケットディスクリプタが返る
失敗: -1が返る
– ソケットディスクリプタはファイルディスクリプタ
の友達(基本はread/write)

参照:参考図書の84-85page
TCPを利用してsocketを開こう!

とりあえずソケットを開く
sd = socket(AF_INET, SOCK_STREAM, 0);
AF_INETの場合の利用されるIPv4の上位層
•SOCK_STREAM
TCP
•SOCK_DGRAM
UDP
•SOCK_RAW
なし
初期状態
接続待機状態(Listen)
クライアント
プロセス
Port A
サーバ
プロセス
Port B
Port C
ホストA
IP Address: xx.xx.xx.xx.
ホストB
IP Address: xx.xx.xx.xx.
SocketをOpen
接続待機状態(Listen)
クライアント
プロセス
Port A
サーバ
プロセス
Port B
Port C
ホストA
IP Address: xx.xx.xx.xx.
ホストB
IP Address: xx.xx.xx.xx.
サーバに接続しよう!



サーバのあがっているIPアドレスとポート
番号を指定し、sockaddr_in構造体に設
定
その情報をconnect()システムコールの引
数として設定。
目的ホストのIPアドレスを調べて、IPアドレ
スとポート番号を設定する
connect()システムコール





int connect(int sock, const struct
sockaddr *address, size_t address_len);
Addressで指定されたプロセスと接続する
成功: 0
失敗: -1
TCPの場合(AF_INET/SOCK_STREAM)
– Active open
サーバと接続
サーバのIPアドレスとポート番号を指定して
Connect()
通信確立状態(Establish)
クライアント
プロセス
Port X
Port A
サーバ
プロセス
Port B
Port C
ホストA
IP Address: yy.yy.yy.yy
ホストB
IP Address: xx.xx.xx.xx.
ソケットの状態を確認

クライアント側でnetstat –a
– すべてのソケットの状態を表示
TCP
Local Address
yy.yy.yy.yy.X
Remote Address
xx.xx.xx.xx.A
State
ESTABLISHD
サーバ通信
•ソケットディスクリプタを読み書きするだけ
•IPアドレスもポート番号も気にする必要はない
•サーバとクライアント同士が通信するためのプ
ロトコル
クライアント
プロセス
GET /index.html
<TITLE>Title</TITLE>
<BODY>…………
サーバ
プロセス
人間メーラ
% tcp_connect mail.sfc.keio.ac.jp 25
helo jp
 あいさつ
mail from: hiddy
 メールの送り元 アドレス
rcpt to: hiddy
 メールのあて先アドレス
data
 メールのデータの始まりを指示
最近寒くなってきて
どうしたこうした
.
 データの終了を指示
^D
%
まとめ

TCPクライアントのプログラムは、
– Socketを開く
– サーバの名前からIPアドレスを調べる
– IPアドレスとport番号からサーバに
connect()
– そのソケットを利用し、read/write
– 最後にclose()
自分でやってみよう


今日渡したサンプルプログラムはsoiの
ページからたどれるようにします。
それをコンパイルして、実際に接続してみ
よう
– % gcc tcp_connect.c –lnsl –lresolv
–lsocket
– 今日の課題
今週の課題

今日作り上げるプログラムを利用して、人間ブラ
ウザまたは人間メーラになろう.ポート番号80番
でWWWサーバ, ポート番号25番でメールサー
バがあがっている。そのログを記録し、考察して
ください
– 必ずやってほしいこと
• 自分の名前で自分にメール
• 友達の名前で自分にメール

このプログラムは完全でない。欠点を挙げよ。
締め切り


10月18日午後11時59分59秒
いつもどおりSOIのシステムで提出