>백엔드 개발 >PHP 튜토리얼 >PHP에서 소켓 서버 설정 및 테스트에 대한 튜토리얼

PHP에서 소켓 서버 설정 및 테스트에 대한 튜토리얼

小云云
小云云원래의
2018-03-02 09:20:363002검색

이 기사는 주로 PHP에서 소켓 서버를 구축하고 테스트하는 방법에 대한 튜토리얼을 공유합니다. 도움이 되기를 바랍니다.

1. 소켓 서버 구축 아이디어

1) 목적: 소켓 서버의 작동 메커니즘 이해

2) 아이디어: 소켓 생성 -> 정보 -> 핸드셰이크 작업 -> 메시지 보내기

2.socket 서버 코드

참고: PHP 파일에 복사하면 명령줄에서 직접 실행할 수 있으며 다른 지원은 필요하지 않습니다.

특별 참고 사항: Chinese_sendMsg, json_encode() 전송이 완료되었습니다

<?php/** * Socket服务器 * @author wuchangliang 2018/1/17 */class SocketServer{    private $sockets; //连接池    private $master;    private $handshake;    /**     * @param $address     * @param $port     */    public function run($address, $port)    {        //配置错误级别、运行时间、刷新缓冲区        echo iconv(&#39;UTF-8&#39;, &#39;GBK&#39;, "欢迎来到PHP Socket测试服务。 \n");        error_reporting(0);        set_time_limit(0);        ob_implicit_flush();        //创建socket        $this->master = $this->_connect($address, $port);        $this->sockets[] = $this->master;        //运行socket        while (true) {            $sockets = $this->sockets;            $write = NULL;            $except = NULL;            socket_select($sockets, $write, $except, NULL); //$write,$except传引用            foreach ($sockets as $socket) {                if ($socket == $this->master) {                    $client = socket_accept($socket);                    $this->handshake = false;                    if ($client) {                        $this->sockets[] = $client; //加入连接池                    }                } else {                    //接收信息                    $bytes = @socket_recv($socket, $buffer, 2048, 0);                    if ($bytes <= 6) {                        $this->_disConnect($socket);                        continue;                    };                    //处理信息                    if (!$this->handshake) {                        $this->_handshake($socket, $buffer);                    } else {                        $buffer = $this->_decode($buffer);                        $this->_sendMsg($buffer, $socket);                    }                }            }        }    }    /**     * 创建socket连接     * @param $address     * @param $port     * @return resource     */    private function _connect($address, $port)    {        //创建socket        $master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)        or die("socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n");        socket_bind($master, $address, $port)        or die("socket_bind() failed: reason: " . socket_strerror(socket_last_error($master)) . "\n");        socket_listen($master, 5)        or die("socket_listen() failed: reason: " . socket_strerror(socket_last_error($master)) . "\n");        return $master;    }    /**     * 握手动作     * @param $socket     * @param $buffer     */    private function _handshake($socket, $buffer)    {        //握手动作信息        $buf = substr($buffer, strpos($buffer, 'Sec-WebSocket-Key:') + 18);        $key = trim(substr($buf, 0, strpos($buf, "\r\n")));        $new_key = base64_encode(sha1($key . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true));        $new_message = "HTTP/1.1 101 Switching Protocols\r\n";        $new_message .= "Upgrade: websocket\r\n";        $new_message .= "Sec-WebSocket-Version: 13\r\n";        $new_message .= "Connection: Upgrade\r\n";        $new_message .= "Sec-WebSocket-Accept: " . $new_key . "\r\n\r\n";        //记录握手动作        socket_write($socket, $new_message, strlen($new_message));        $this->handshake = true;    }    /**     * 断开socket连接     * @param $socket     */    private function _disConnect($socket)    {        $index = array_search($socket, $this->sockets);        socket_close($socket);        if ($index >= 0) {            array_splice($this->sockets, $index, 1);        }    }    /**     * 发送信息     * @param $buffer     * @param $client     */    private function _sendMsg($buffer, $client)    {        $send_buffer = $this->_frame(json_encode($buffer));        foreach ($this->sockets as $socket) {            if ($socket != $this->master && $socket != $client) { //广播发送(除了自己)                socket_write($socket, $send_buffer, strlen($send_buffer));            }        }    }    /**     * 解析数据帧     * @param $buffer     * @return null|string     */    private function _decode($buffer)    {        $len = $masks = $data = $decoded = null;        $len = ord($buffer[1]) & 127;        if ($len === 126) {            $masks = substr($buffer, 4, 4);            $data = substr($buffer, 8);        } else if ($len === 127) {            $masks = substr($buffer, 10, 4);            $data = substr($buffer, 14);        } else {            $masks = substr($buffer, 2, 4);            $data = substr($buffer, 6);        }        for ($index = 0; $index < strlen($data); $index++) {            $decoded .= $data[$index] ^ $masks[$index % 4];        }        return $decoded;    }    /**     * 处理返回帧     * @param $buffer     * @return string     */    private function _frame($buffer)    {        $len = strlen($buffer);        if ($len <= 125) {            return "\x81" . chr($len) . $buffer;        } else if ($len <= 65535) {            return "\x81" . chr(126) . pack("n", $len) . $buffer;        } else {            return "\x81" . char(127) . pack("xxxxN", $len) . $buffer;        }    }}$sc = new SocketServer();$sc->run('127.0.0.1', 2046);

3. 고객 종료 코드

참고: html로 직접 복사하여 위 php 파일과 같은 폴더에 넣으세요. 2레이어 구문 분석에 특히 주의하세요. onmessage 구문 분석

<!DOCTYPE html><html><head>    <meta charset="utf-8" />    <title>WebSocket Test</title>    <script language="javascript"type="text/javascript">        websocket = new WebSocket('ws://127.0.0.1:2046/');        websocket.onopen = function(evt) {            console.log('connect');            websocket.send('{"data":"您好,世界!"}');        };        websocket.onclose = function(evt) {            console.log('onclose');            console.log(evt);        };        websocket.onmessage = function(evt) {            console.log('onmessage');            if (evt.data) {                console.log(JSON.parse(JSON.parse(evt.data)));            }        };        websocket.onerror = function(evt) {            console.log('onerror');            console.log(evt);        };        function sendMsg(){            var sendData = { 'data': document.getElementById('name').value};            websocket.send(JSON.stringify(sendData));        }    </script></head><body>    <h2>WebSocket Test</h2>    <input type="text" name="name" id="name" />    <a href="javascript:;" onclick="sendMsg()">点击发送</a></body></html>

4. 테스트 예


관련 권장 사항:

PHP를 사용하여 소켓 서버를 구현하는 방법

PHP 튜토리얼에서 소켓 서버로 데이터 보내기 및 받기

java 스크립트 - SegmentFault

를 사용하여 WebSocket 서버를 구성하는 방법

위 내용은 PHP에서 소켓 서버 설정 및 테스트에 대한 튜토리얼의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.