class: title, smokescreen, shelf, no-footer # <small>トランスポート層<br>- ダイジェスト -</small> <div class=footnote> <small><small> アプリケーション層 通常版は、こちら: <A HREF="/slides/network/tcpip/tpt_tcp">[TCP]</A>, <A HREF="/slides/network/tcpip/tpt_udp">[UDP]</A>, <A HREF="/slides/network/tcpip/tpt_quic">[HTTPそれから(QUIC,HTTP/3)]</A> and <A HREF="https://www.youtube.com/playlist?list=PLS2cEmI21XYKUWdzZyvjE3mO0YuNIu0lQ"> [動画再生リスト] </A> </small></small> </div> --- class: img-right,compact # 全体像(再掲) ![width640px](/images/network/end-to-end.png) <small> - 右図: ホストとホストの通信 - ホスト = コンピュータ - END TO END (端〜端)通信 - 用語: 階層(Layer), 〜層 - 用語: プロトコル(取り決め,約束事) - TCP,IP,Ethernetなど - 用語: サーバ,クライアント - 右図: サーバ(左)とクライアント(右) - サーバ (写真の業務用PC) - サービスを提供する側 - WWWサーバ,メールサーバ - クライアント (右端のPC) - サービスを受ける側(お客様) - ブラウザやメールソフト - 人間が操作しているPC </small> --- class: img-right,compact # トランスポート層 <div class=footnote> <small><small> (脚注) インターネットの初代転送プロトコルはNCPで、TCPは第2世代です。 ちょうど40年前、1983/01/01にTCP/IPへ切り替えました。 40年も使うとは思っていなかったのですが、なんだかんだ使いました。 どんな品質が悪くてもつながることがTCPの主眼であって、 いまのように安定して高速なネットワークで使う想定ではありません。 そのためTCPにはオーバスペックな面が色々あります。 <br> そういうわけで、 最新の話題は、いかにしてTCPを辞めるか?です。 実のところ知らない間にTCPからUDPベースのQUICへ切り替えが進んでいます (使えるときにはGoogle ChromeなどがQUICを使っています)。 いまインターネット全体の20%くらいがQUICです </small></small> </div> ![width640px](/images/network/end-to-end.png) <small> - 上から2番目の階層が**トランスポート層** - この層を代表するプロトコルがTCPとUDPです。 インターネットと言えば**TCP/IP**と言われるくらいで、 **インターネットを代表する技術体系**です - この層の上の通信の区別は**ポート番号**という数字で行います。 TCPを使う場合「数字/tcp」という表記法がよく使われます。 (アプリケーション)プロトコルとポート番号は組なので、 **HTTP**と**80/tcp**は同義語です。 他の例: **SSH = 22/tcp** </small> --- class: title, smokescreen, shelf, no-footer # <small>Part 1: TCP<br>Transmission Control Protocol</small> <div class=footnote> <small><small> </small></small> </div> --- class: img-right,compact # TCP: 信頼性のあるデータストリーム通信を提供します <div class=footnote> <small><small> </small></small> </div> ![height240px](/slides/network/tcpip/tpt_tcp/images/telephone_kokusai_denwa.png) ![height240px](/slides/network/tcpip/tpt_tcp/images/sweets_tokoroten_tentsuki.png) ![height240px](/slides/network/tcpip/tpt_tcp/images/kids_nagashisoumen.png) ![height240px](/slides/network/tcpip/tpt_tcp/images/kawa.png) <small> - END-TO-ENDで信頼性のあるデータ転送の仕組みを提供します。 地球の反対側まで20,000kmあろうとも(速度はともかく)通信できます - **データストリーム**はTCPによってパケット群に分割され転送されます - データストリームとは? ... <br> 転送するデータに特定の構造は仮定しません。 **ところてん**もしくは**流しそうめん**のように、 入れたものがバイト単位で反対側から次々と出てくるイメージです (注意: TCPでは同じ通信路で返事も返ってくるため、 一方通行に聞こえる**流しそうめん**は少しよくない例えですが、 ストリーム(流れ)のイメージとしては良いでしょう) </small> --- class: img-right,compact # TCP: 信頼性 <div class=footnote> <small><small> (脚注) 本当にいろいろな品質のネットワークがあるので、 複雑なリカバリができないと障害時や僻地との通信は難しい。 どんな品質でも接続し続けられることが本来の主目標と考えられます (現実とずれてきている...) </small></small> </div> ![](/slides/network/tcpip/tpt_tcp/images/tcp-reliable.png) - 論理的な(仮想)通信路(**コネクション**)を構築し、その上でパケットを転送します。 **コネクション指向**とも呼ばれます。 逆に後述のUDPは**コネクションレス** - つねに通信の状態をモニタし、エラー訂正などはTCPが担当します (アプリケーションはエラーに気づきません) - **パケットの損傷、紛失、重複、順序の乱れを修復**します。 必要ならパケットを**再送**します - 状態があり、それをモニタしているわけで、 つまりTCPは**ステートフル**なプロトコルの例です --- class: img-right,compact # TCP: フローコントロール <div class=footnote> <small><small> (脚注) 送れそうなら、どんどん送ります(転送速度をあげます) </small></small> </div> ![](/slides/network/tcpip/tpt_tcp/images/tcp-reliable.png) - **フローコントロール**(流量調節) - 相手ホストの忙しさ(仕事量)の具合や回線品質によって送信頻度を自動的に調節しています - (スライドの最後の方(中間試験範囲外)で基本動作を少し解説しています) --- class: img-right,compact # TCP: TCPとIPはコンビです <div class=footnote> <small><small> (脚注1) 「パケットを落とす」という表現があります (脚注2) IPは普通郵便(その家の郵便受けには入れますが相手に届いているかは未確認)、 TCPは書留(相手に届いたことまで確認する)というイメージはどうでしょうね? </small></small> </div> ![](/slides/network/tcpip/tpt_tcp/images/tcp-reliable.png) - TCPはIPとコンビで動作します - だからTCP/IPというセットの名称 - **誰(アプリ)宛**に渡すのか?は**TCP(トランスポート層)が面倒を見ます** - **IPは住所まで(だけ)**の面倒を見ます - IPは転送途中で何かあっても気にしませんので、 きちんと**データが届いているかはTCPが気にかけます** --- class: img-right,compact # TCP: 多重化(multiplexity) <div class=footnote> <small><small> (脚注) 一つのWWWサーバに、 あるPC上から複数のアプリケーション(クライアント)が接続している場合、 クライアントのポート番号以外は、すべて同じになります i.e. 図の青線と赤線の通信では、 (サーバのIPアドレス,サーバのポート,クライアントのIPアドレス)の3つ組は同じですが、 クライアントのポートだけ異なります </small></small> </div> ![](/slides/network/tcpip/tpt_tcp/images/tcp-multiplexity.png) - 多重化(multiplexity) - ポート番号とIPアドレスの対で通信路を区別するので、 ホスト間で同時に複数のTCP通信路を利用可能 - **サーバのIPアドレス,サーバのポート(80/tcp),クライアントのIPアドレス,クライアントのポート(ランダム)**の4つの情報の組で識別できます --- class: img-right,compact # データストリーム <!-- ![height240px](images/kids_nagashisoumen.png) --> ![width240px](/slides/network/tcpip/tpt_tcp/images/kawa.png) ![width240px](/slides/network/tcpip/tpt_tcp/images/money_tsuchou_cashcard.png) ![height240px](/slides/network/tcpip/tpt_tcp/images/CC0_Ibm_punch_card.png) - 入力したデータが反対側から**1オクテット**(8ビット=1バイト)ずつ出てきます - 改行などは特別なコードを決めてありエディタなどが理解しています (ファイルを表現するための取り決め) - 例: Unixファイルの改行(line feed) <br> **012**(8進数) **0A**(16進数) - 例: ストリームの反対の例として1行80文字制限というデータ構造(右図の下) - 大昔のpunchcardでprogramming - データが無いところは空白?...非効率 - 紙幣と同じ機材が使いまわせそう - 印刷を考えると便利そう(適材適所?) <div class=footnote> <small><small> (注)1オクテットという表現: 昔のコンピュータでは1バイトが8ビットとは限らないため </small></small> </div> --- class: img-right,compact # パケットへの分割 <div class=footnote> <small><small> (脚注) ソケット(socket) ... ネットワークのプログラミングでは、 いつもの標準入出力(e.g. STDIN,STDOUT)と異なるsocketという入出力機構を使います。 このためソケットプログラミングとも呼ばれます。 BSD UnixがTCP/IPを実装したときに、この仕組みを作りました </small></small> </div> ![](/slides/network/tcpip/tpt_tcp/images/tcp-reliable.png) <small> - データストリームはTCPによってパケット群に分割され転送されます (右図の箱の列を見よ) - アプリケーションは任意の長さのデータを送信/受信できます(**socket**への入出力) - TCPがデータをある長さ(**セグメント**サイズ)に分割して送信し、 (受信側で)再構成しています - セグメントサイズはTCPより下の層次第で可変です(だいたい1400バイト前半が多いか?) - セグメントはTCPヘッダとIPヘッダ分を差引いたサイズになります。 例: 1500 - 20 - 20 - 1500とは? = イーサネットのペイロードサイズ=1500バイト(IP,TCPヘッダ含)のことです。 なお、一般家庭などのB-FletsはPPPoEなので1500より小さくなります(詳細は略) </small> --- class: col-2,compact # TCPヘッダ <small> | 図中の表現 | 内容 | 長さ | |----------------------------|--------------------|------| | source port | 送信元のポート番号 | 16 | | destination port | 送信先のポート番号 | 16 | | **sequence number** | シークエンス番号 | 32 | | **acknowledgement number** | アクノリッジ番号 | 32 | | data offset | ヘッダの長さ | 4 | | reserved | 予約(未使用) | 6 | | **control bits** | 制御命令/状態 | 6 | | **window** | 流量制御 | 16 | | checksum | チェックサム | 16 | | urgent pointer | 緊急ポインタ | 16 | </small> ![height400px](/slides/network/tcpip/tpt_tcp/images/tcp-header.png) <div class=footnote> <small><small> (脚注1)ヘッダ構造は覚えなくてOK <br> (脚注2)予約の3ビット分はECNへ;RFC3168(2001) </small></small> </div> --- class: img-right,compact # TCPヘッダ <div class=footnote> <small><small> (脚注) ヘッダ構造は覚えなくてOK; ヘッダにポート番号がありますよね?そこだけ覚えておいて欲しいですね </small></small> </div> ![height400px](/slides/network/tcpip/tpt_tcp/images/tcp-header.png) - 信頼性、フローコントロール、多重化のための情報がヘッダにあります - **ポート番号はありますが、IPアドレスは無い**ことに注意してください - トランスポート層(TCP)の担当は**アプリケーションの区別(誰?)**です - TCPヘッダにあるのは、ポート番号とTCPを制御する情報 - インターネット層がIPアドレス(住所)を扱うので、 IPヘッダにIPアドレスが書いてあります <br> <small> **TCPとIPはコンビで動作することを忘れずに!** </small> --- class: img-right,compact # TCPヘッダとTCPの動作 <div class=footnote> <small><small> (脚注) 詳細は(中間試験範囲外になる)TCP編の最後のあたりで解説しています。 このあたりのTCPヘッダ詳細は、すでに応用情報処理試験の範囲すら越えていますが、 ネットワークの授業としてはビギナー編です。 プロのエンジニアを目指す人にとってTCPの基本動作は必須要件なので各自で勉強してください (TCPの動作がわからないと基本的な障害対応すらできない)。 IPAの試験群がソフトウエアに偏重してるだけなので、 TCPなんて分からなくてOKなどと勘違いしないようにしてください </small></small> </div> - TCPは、まずコネクションを確立するところから始まります。 仮想通信路の生成もしくはコネクションの初期化とも言えます。 - この初期化が**3-way ハンドシェイク**と呼ばれる有名な手法です。 TCPヘッダの Control bits で命令(**SYN** = シンクロナイズ命令)を送り、 sequence number と acknowledge number をモニタして、 サーバとクライアントが互いに確認(**ACK**, acknowledge が確認という意味)を取りながら行います (詳細は[こちら](/slides/network/tcpip/tpt_tcp/#tcp-details)以降を参照) --- class: title, smokescreen, shelf, no-footer # <small>Part 2: UDP<br>User Datagram Protocol</small> <div class=footnote> <small><small> </small></small> </div> --- class: img-right,compact # UDPヘッダ ![](/slides/network/tcpip/tpt_udp/images/udp-unreliable.png) - TCPと違い、最小限の情報のみです - **処理が軽いです** - 最低限の通信はできますが、 パケットの損傷、紛失、重複、順序の乱れなどについて何も配慮しません - 右図は、UDPやIP、イーサネットのレベルのあちこちでパケットが損失するイメージです。 TCPであればTCPが回復させますが、**UDPでは単にパケットが届かない**だけです (たいていは、**エラーの連絡もありません**) --- class: col-2,compact # UDPヘッダ - TCPと違い、最小限の情報のみです - **処理が軽い** - 最低限の通信はできますが、 パケットの損傷、紛失、重複、順序の乱れなどについて何も配慮しません - 障害への対処は、すべてソフトウエア内に書く必要があります - そのかわり、 **プログラマつまりユーザがプロトコルをすべてコントロールできるのがメリット**です <wbr> ![height240px](/slides/network/tcpip/tpt_udp/images/udp-header.png) | 図中の表現 | 内容 | 長さ | |----------------------------|--------------------|------| | source port | 送信元のポート番号 | 16 | | destination port | 送信先のポート番号 | 16 | | length | データの長さ | 16 | | checksum | チェックサム | 16 | --- class: col-2,compact # UDPを使っている例 <div class=footnote> <small> (脚注1) DNSクエリのデフォルトはUDPでも、サーバ間の設定ファイルの同期はTCP <br> (脚注2) 組み込み機器などではsoftware(firmware)の格納領域が小さいため、 firmwareを大きくしないために、 UDPで転送するTFTPを使いたいという理由もあります </small> </div class=footnote> - 大域的にUDPを使う例 - DNS (詳細は前回を参照) - 軽い動作 - IP電話などの**音声,動画** - **少々のパケット損失が問題にならない**メディア - 最初の認証などはTCP、 実際のデータ転送はUDPといったハイブリッドな作りが普通です <wbr> - **短距離**通信でUDPを使う例 - 視認範囲、1部屋などの規模感 - OSの自動設定 - DHCP (Dynamic Host Configuration Protocol) - ネットワーク機器の設定やbackup - TFTP (Trivial File Transfer Protocol) --- class: col-2,compact # UDPの意義 <div class=footnote> <small> (脚注) TCPの場合OSがエラー処理など何でも面倒をみてくれて便利です。 アプリ屋さんはデータ転信の詳細など一切気にせずにアプリを作れます。 だから多くのアプリがTCPベースなわけですよ </small> </div class=footnote> - TCPは仮想通信路を確立して転送を行いますが、 その確立する処理自体が重たいという問題があります - TCPはOSの機能なので(プログラマが何かしたくとも)細かな変更は不可能です <wbr> - そこで真逆のUDPという仕組みが用意されており、 TCPにない次のような特徴があります - 軽い動作 - **プログラマが変更可能なプロトコル** (トランスポート層はUDPにまかせて、 その上の階層で自由に設計できるという意味です) ... 前回の**DNS**、このあと紹介するQUIC(HTTP/3)などが、この好例と言えます