14
14

More than 5 years have passed since last update.

テスト用にPHPで簡単なTCPサーバを書いた

Last updated at Posted at 2014-05-17
server.php
<?php

class TestTCPServer
{
    public $sock = NULL;

    public function __construct($addr = "127.0.0.1", $port = 5000)
    {
        $sock = $this->newSocket($addr, $port);
        $this->sock = $sock;
    }

    public function newSocket($addr, $port)
    {
        if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
            throw new \Exception("socket_create() failed: ".socket_strerror(socket_last_error()));
        }

        if ((socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1)) === false) {
            throw new \Exception("socket_set_option() failed: ".socket_strerror(socket_last_error()));
        }

        if ((socket_bind($sock, $addr, $port)) === false) {
            throw new \Exception("socket_bind() failed: ".socket_strerror(socket_last_error($sock)));
        }

        if (socket_listen($sock) === false) {
            throw new \Exception("socket_listen() failed: ".socket_strerror(socket_last_error($sock)));
        }

        return $sock;
    }

    public function run(Closure $code)
    {
        while ($remote = socket_accept($this->sock)) {
            while ($line = socket_read($remote, 1024)) {
                $code($remote, $line, $this->sock);
            }
        }
    }
}

データを受信した後の処理は、コールバックで書くようにしている。
echoサーバを書く場合は、以下のようになる。

echo_server.php
<?php

require_once 'server.php';

$server = new TestTCPServer();
$server->run(function($remote, $line, $sock) {
    socket_write($remote, $line);
});

実行するとブロックするので、
バックグランドで実行しつつ、以下のように動作確認できる。

$ telnet 127.0.0.1 5000
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
test message
test message

クライアント側もPHPで書くとしたら、以下のようになる。

echo_client.php
<?php

if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
    die("socket_create() failed: ".socket_strerror(socket_last_error()));
}

if (socket_connect($sock, '127.0.0.1', 5000) === false) {
    die("socket_connect() failed: ".socket_strerror(socket_last_error()));
}

$buf = "foo\n";
socket_write($sock, $buf, strlen($buf));
echo socket_read($sock, strlen($buf));

$buf = "bar\n";
socket_write($sock, $buf, strlen($buf));
echo socket_read($sock, strlen($buf));

socket_close($sock);

参考

14
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
14