PHP中socket的使用

SOCKET编程

简单的TCP/IP服务器

class SocketServer 
{
    private $ip = '';
    private $port = '';
    private $err_msg = '';
    public function __construct($ip,$port)
    {
        $this->ip = $ip;
        $this->port = $port;
        $this->create_socket();
    }

    protected function create_socket()
    {
        // 三个返回socket资源的方法 : socket_create socket_accept socket_create_listen
        
        $sock = socket_create(AF_INET,SOCK_STREAM,getprotobyname('tcp'));
        if ($sock === false) {
            $this->fail();
        }

        // 绑定ip,port
        $retval = socket_bind($sock,$this->ip,$this->port);
        if ($retval === false) {
            $this->fail();
        }

        // 监听端口
        $retval = socket_listen($sock);
        if ($retval === false) {
            $this->fail();
        }     

        while (true) {
            // socket_accept会阻塞直至有连接或失败才返回
            if (($msg_sock = socket_accept($sock)) === false) {
                break;
            }
            if (!$msg_sock) {
                echo "有客户端链接\n";
            }
            $msg = "\nwelcome\n";
            socket_write($msg_sock,$msg,strlen($msg));

            // 循环判断socket是否有新的数据,没数据返回""
            while (true) {
                if (($msg = socket_read($msg_sock,1024,PHP_NORMAL_READ)) === false) {
                    break 2; // 跳出两层循环
                }
                // trim 去取 \n \r \0 空格..
                if (!$msg = trim($msg)) {
                    continue; // 空数据
                }
                if ($msg == 'quit') {
                    break;
                } elseif ($msg == 'shutdown') {
                    socket_close($msg_sock); 
                    break 2; // 跳出两层循环                   
                } else {
                    $retval = "\nYou just say " . $msg . "\n";
                    socket_write($msg_sock,$retval,strlen($retval));   
                    echo 'server receive msg : ' . $msg . "\n";           
                }
            }
            socket_close($msg_sock);
        }
        socket_close($sock);
    }

    protected function fail()
    {
        $err_no = socket_last_error();
        $this->err_msg = socket_strerror($err_no);
        echo "\n" . $this->err_msg ."\n";
        exit;
    }
}

set_time_limit(0);
$ip = "0.0.0.0";
$port = 8000;
$socket = new SocketServer($ip,$port);

简单的TCP/IP客户端

class SocketClient 
{
    private $ip = '';
    private $port = '';
    public function __construct($ip,$port,$uri)
    {
        $this->ip = $ip;
        $this->port = $port;
        $this->uri = $uri;
        $this->connect();
    }   

    protected function connect()
    {
        $sock = socket_create(AF_INET,SOCK_STREAM,getprotobyname('tcp'));
        $retval = socket_connect($sock,$this->ip,$this->port);
        if ($retval === false) {
            $this->fail();
        }
        // 写
        $in  =  "HEAD {$this->uri} HTTP/1.1\r\n";
        $in  .=  "Host: {$this->ip}\r\n";
        $in  .=  "Connection: Close\r\n\r\n"; // 注意两个\r\n表示结束
        socket_write($sock,$in,strlen($in));
        // 读
        $out = '';
        while ($retval = socket_read($sock,1024)) {
            $out .= $retval;
        }
        echo $out;
        socket_close($sock);
    } 

    protected function fail()
    {
        $err_no = socket_last_error();
        $this->err_msg = socket_strerror($err_no);
        echo "\n" . $this->err_msg ."\n";
        exit;
    }
}

$ip = "119.29.149.18";
$port = 80;
$uri = "/contract/";
$socket = new SocketClient($ip,$port,$uri);

标签: none