2.1 2種類のインターネットソケット
これは何?インターネットソケットには2種類ある?そうです。まあ、違うけど。嘘です。もっとあるんだけど、怖がらせたくなかったんだ。ここでは2種類しか話しません。ただし、この文章では、"Raw Sockets" も非常に強力なので、ぜひ調べてみてくださいと言うつもりです。
わかったよ、もう。この2つのタイプは何ですか?一つは "ストリームソケット"、もう一つは "データグラムソケット" で、以下、それぞれ "SOCK_STREAM
" "SOCK_DGRAM
" と呼ぶことがあります。データグラムソケットは "コネクションレス型ソケット" と呼ばれることもあります 。(ただし、本当に必要であれば connect()
を使用することができます。後述の connect()
を参照してください。)
ストリームソケットは、信頼性の高い双方向接続の通信ストリームです。ソケットに2つのアイテムを "1, 2" という順序で出力すると、反対側にも "1, 2" という順序で届きます。また、エラーも発生しません。実際、私はエラーフリーであることを確信しています。もし、そうでないと主張する人がいたら、耳に指を突っ込んで "ララララ" と唱えてやりたいくらいです。
何がストリーム・ソケットを使うのでしょうか?さて、皆さんは telnet
というアプリケーションをご存知でしょうか?あれはストリームソケットを使っているんです。あなたが入力した文字は、すべて入力した順番に到着する必要がありますよね?また、Webブラウザは HTTP(Hypertext Transfer Protocol)を使っていますが、これはストリームソケットを使ってページを取得します。実際、80番ポートで Web サイトに telnet して、"GET / HTTP/1.0
" と入力してリターンを2回押すと、HTML がダンプされて戻ってきますよ。
もし telnet
がインストールされておらず、インストールもしたくない場合、あるいは telnet
がクライアントとの接続にうるさい場合、ガイドには telnot
という telnet
に似たプログラムが付属しています。これは、このガイドで必要なものすべてに対してうまく機能するはずです。(なお、telnet は実際には spec'd networking protocol であり、telnot
はこのプロトコルを全く実装していません。)
ストリームソケットは、どのようにしてこの高いレベルのデータ伝送品質を実現しているのでしょうか。 それは、"TCP" として知られる "伝送制御プロトコル"(TCP の詳細については RFC 793 を参照)というプロトコルを使用しているからです。TCP はデータが順次、エラーなく到着することを確認します。"TCP" は "TCP/IP" の半分で、"IP" は "Internet Protocol"(RFC 791 を参照)の略だと聞いたことがあるかもしれません。IP は主にインターネット・ルーティングを扱い、一般にデータの完全性には責任を持ちません。
かっこいい。データグラムソケットについてはどうでしょうか?なぜコネクションレス型と呼ばれるのでしょうか?どうなっているんだ?なぜ信頼性が低いのでしょうか?データグラムを送ると、それが届くかもしれません。データグラムを送信すると、それは到着するかもしれません。もし到着すれば、パケット内のデータはエラーフリーです。
データグラムソケットもルーティングに IP を使いますが、TCP は使わず、"User Datagram Protocol"、つまり "UDP" を使います(RFC 768 を参照)。
なぜコネクションレスレスなのか?まあ、基本的には、ストリームソケットのようにオープンな接続を維持する必要がないからです。パケットを作り、その上に宛先情報を含む IP ヘッダを貼り付け、送信するだけでいいのです。コネクションは必要ありません。一般的には、TCP スタックが利用できないときや、パケットをいくつか落としても宇宙の終わりを意味しないときに使用されます。サンプルアプリケーション:tftp
(FTP の弟分のようなファイル転送プロトコル)、dhcpcd
(DHCP クライアント)、マルチプレイヤーゲーム、ストリーミングオーディオ、ビデオ会議、などなど。
"ちょっと待った!tftp
と dhcpcd
はバイナリアプリケーションをあるホストから別のホストに転送するために使われるんだ!アプリケーションが到着したときに動作することを期待するならば、データが失われることはありえない!これはどんな黒魔術なんだ?"
さて、私の人間の友人である tftp
やそれに類するプログラムは、UDP の上に独自のプロトコルを載せています。たとえば、tftp プロトコルは、送信されたパケットごとに、受信者は "受け取ったよ!" というパケット("ACK" パケット)を送り返さなければなりません。元のパケットの送信者は、例えば5秒間返信がない場合、最終的に ACK を得るまでパケットを再送信することになります。この確認手続きは、信頼性の高い SOCK_DGRAM
アプリケーションを実装する際に非常に重要です。
ゲーム、オーディオ、ビデオなどの信頼性の低いアプリケーションでは、ドロップしたパケットを無視するか、あるいは巧みに補うようにします。(Quake プレイヤーは、この効果の発現を呪われたラグという専門用語で知っていることでしょう。この場合の "呪われた" という単語は、非常に不敬な発言を意味します。)
なぜ信頼性の低い基礎プロトコルを使うのでしょうか?理由は2つ、速度とスピードです。何が無事に到着したかを追跡し、順序立てて確認したりするよりも、発射して忘れる方がずっと速いのです。チャットメッセージを送るなら、TCP は素晴らしいです。世界中のプレイヤーの位置情報を毎秒40件送るなら、1件や2件が落ちてもそれほど問題ではないので、UDP は良い選択だと思います。