LinuxのようなUNIX系OSでは,ファイルに対する操作と同様にネットワーク通信を行うために,「ソケット」と呼ばれる仕組みを使います。今回はソケットについて学びましょう。

 コンピュータは「電子計算機」という和名が示す通り,本来は高速に計算するための機械でした。しかし,現在のコンピュータは,Webブラウジングや電子メールのやり取りなどに使われることが多く,ネットワークと切り離すことができません。最近は「コンピュータを使う」ことと「ネットワークを使うこと」がかなり同義になっているのではないでしょうか。

 今回は,ネットワークを介した通信の基礎になっている「ソケット」という概念を紹介します。

ディスクリプタでアクセスが単純に

 ソケットはネットワーク通信に用いるファイル・ディスクリプタ(file descriptor)です。そこで,ソケットの説明に入る前に,より一般的なファイル・ディスクリプタについて押さえておきましょう。

 LinuxなどUNIX系OSでは,入出力はすべてバイト列(文字列の一種)として扱われます。入出力では,バイト列のことをストリーム(streamは「流れ」の意味)と呼びます。

 ディスクリプタは単なる整数で,ストリームを区別する識別子として使います。OSはあるプログラム(プロセス)がアクセスしているストリーム一つひとつに固有の番号を付け,その番号をディスクリプタと呼びます。

 ディスクリプタはプロセスごとの固有の値で,0番が標準入力,1番が標準出力,2番が標準エラー出力であると決められています。そのほかのストリームはオープン(利用開始)されるたびに小さい番号から順に使われ,クローズ(利用終了)されると同じ番号が再利用されます。

 ディスクリプタの最も重要な特徴は,ファイル・ディスクリプタが対応しているストリームの接続先が,ローカルのファイルやネットワーク経由の接続というように異なっていても,全く同じように入出力できることです。

 もちろん,OSの内部ではそれぞれの装置に対して処理内容が全く異なります。しかし,ファイル・ディスクリプタを使う限り,プログラムからは同様に扱えます。OSが勝手に接続先に合わせた処理を進めてくれるからです。

 ファイル・ディスクリプタさえあれば,読み出しにはreadシステム・コール,書き込みにはwriteシステム・コールが使えます(図1)。

図1●ファイル・ディスクリプタを用いた入出力
図1●ファイル・ディスクリプタを用いた入出力

 これはオブジェクト指向の「ポリモーフィズム」という考え方そのものです。UNIXの開発が始まったのは1960年代末ごろで,オブジェクト指向の考え方は当時まだ広まってなかったことを考えると,画期的なことだったのではないかと想像します*1

TCP/IPの特徴

 ネットワーク通信にはソケットに加えて,プロトコル(通信手順)が必要です。歴史的にはネットワークを経由して通信を進める手順(プロトコル)は複数ありました。しかし,淘汰が進み,現在生き残っているのはTCP/IPと呼ばれるプロトコルです。TCP/IPは「Transmission Control Protocol(転送制御プロトコル)/ Internet Protocol(インターネット・プロトコル)」の略です。IPはIPアドレスで指定される配送先へデータを送り届けることだけを実現する低位のプロトコルです。TCPはエラー回復,データ再送や流量制御なども担う高位のプロトコルです。

 TCP/IPと総称するときには,UDP(User Datagram Protocol)を含むこともあります。UDPはIPにごく薄い皮をかぶせたプロトコルです。TCPと比較すると次に挙げる4つの点で異なります。

●通信データ長が保存される

 TCPはストリーム型なので,送信したデータはバイト列としてやり取りされます。実際の通信ではストリームはある一定の大きさのデータ(パケット)に分割されますが,TCPのレベルで連結されてしまい,個々のパケットの情報は分かりません。

 一方,UDPは送ろうとしたデータをそのままパケットとして送信します(長すぎるものは分割します)ので,ひとまとめに送ったデータの長さが送信先まで保存されます。このような通信をデータグラム通信(Datagram)と呼びます。

●エラー訂正がない

 送られたデータがネットワークを経由して,送信先まで届く間に何らかの事情でパケットが失われることがあります。TCPではパケットに通し番号を付けていて,届くべきパケットがまだ届かない場合,「何番のパケットがまだ届いていませんよ」とデータの再送を依頼し,データの抜けがないようにします。また,ネットワークが混雑しているときには一度に送るパケットの大きさや量を調節し,ネットワークが「詰まって」しまわないような工夫も施します。

 一方,UDPはそのような処理をしませんから,「送ったはずのデータが届かない」という事態にはプログラムが自ら対処する必要があります。

●接続が不要

 TCPでは通信の相手先は固定されます。複数の相手と通信するときには,それぞれ別のソケットを用意する必要があります。

 一方,UDPでは送信先を明示するsendtoシステム・コールを用いることでデータ送信ごとに違うあて先に送れます。データ受け取りの方は送信元の情報も一緒に受け取るrecvfromシステム・コールを使えます。接続が不要なUDPですが,必要であれば明示的に接続することで相手先を固定できます。

●高速処理

 TCPは,プログラムなどより上位のレイヤーから簡単に利用できるように,複雑な制御を行っています。それだけ仕事が多いわけで,リアルタイム性に欠ける場合があります。

 一方,UDPは処理内容が非常に単純なので,IPそのものの性能を引き出せます。データ転送の信頼性よりもリアルタイム性が重視されるネットワーク・アプリケーションでは,性能面からUDPを選ぶこともあります。