ひとりアドベントカレンダー2015 第22日目 〜 PHPer でもソケットプログラミングしてみたい

  • このエントリーをはてなブックマークに追加
  • Pocket

22日目になりました。完走までもう一息。

きょうも引き続き「ぺちぱーでも○○してみたい」シリーズをお届けです。お題はソケットプログラミング。PHP 公式マニュアルの例に沿って簡易なエコーサーバーを作ってみます。

ソケットとは?

ソケットは UNIX 系 OS におけるプロセス間通信に使う API です。Wikipedia によると、

ソケット: Socket)とは、BSDUNIXを起源とするAPIであり、C言語によるアプリケーション開発でのプロセス間通信、特にコンピュータネットワークに関するライブラリを構成する。BSDソケットバークレーソケットなどとも呼ばれる。

1983年にリリースされたUNIXオペレーティングシステム(OS) 4.2BSD で初めて API として実装された。ネットワークの抽象化インタフェースとしてのデファクトスタンダードとなっている。伝統的なSocket APIはC言語を対象とするが、他のプログラミング言語でも類似のインタフェースを用意している事が多い。

とあります。同じマシン内のプロセスだけでなく、ネットワークをまたいだ通信も行えます。いわゆる TCP/IP 通信も主にソケットを使って行われているかと思います。PHP にもソケットを扱う API が用意されています。今日はそれについて見ていきます。

 

エコーサーバー

ソケットプログラミングの入門として必ず挙げられるのが、相手が送信してきた文字列をそのまま送り返す「エコーサーバー」と呼ばれるサーバーです。PHP 公式マニュアルにもこれの例が載っているのでそれを試してみます:

例1 ソケットの例: 簡易 TCP/IP サーバー

コードはこの例のとおりなので要点のみを書いていきます。

接続待ち受け

ソケットで TCP 通信を待ち受けるサーバーを作るには以下の手順を踏む必要があります:

  1. ソケットを作成する ( create)
  2. 作成したソケットをIPアドレス/ポートに紐付ける (bind)
  3. そのポートを監視する(listen)
  4. 通信相手(クライアント)がアクセスしてくるのを待って、接続する(accept)

PHP でこれらの手順に対応する関数は以下のとおりです:

そのままの名前で大変わかりやすいですね。

メッセージループ

ひとたび接続が確立されれば、相手との通信はソケットの読み書きをすることで行えます。ソケットはコード上ではファイルディスクリプタのように見え、ファイルの読み書きと同じような感じに扱えます。

  • ソケットへの書き込みは socket_write() で行います。
  • ソケットからの読み込みは socket_read() で行います。

 

実行してみる

例のプログラムを実行してみます。起動すると接続待ち状態になります:

server_php

 

この状態でターミナルの別窓を開き、telnet でアクセスするとサーバーから応答があります:

telnet

telnet からなにか文字を入力するとそれがそのまま返ってきます。サーバー側の標準出力にも表示されます:

connection

まとめ

PHP のソケット API を使って簡易なエコーサーバーを作ってみました。このようなプログラムは C や C++ で書かれることが多いと思われますが、 PHP でもできるのですね。この例では接続がひとつしか受け付けられません。実用的なサーバーにするには多重に接続できるようにする必要がありますね。また、デーモン化してバックグラウンドプロセスとして動くようにしたほうがよさそうです。

明日あたりにこの辺りをやれればと思います。

 

 

  • このエントリーをはてなブックマークに追加
  • Pocket

SNSでもご購読できます。

コメントを残す

*