0

0

PHP之Socket服务器搭建和测试实例分享

小云云

小云云

发布时间:2018-03-13 13:20:45

|

1828人浏览过

|

来源于php中文网

原创

1.socket服务器搭建思路

1) 目的:理解socket服务器工作机制

2) 思路:创建socket -> 把socket加入连接池 -> 处理接收信息 -> 握手动作 -> 发送信息

2.socket服务器代码

注:复制到php文件,直接命令行可以运行,不需要其他支持

特别注意:为了能传输中文_sendMsg做了json_encode()

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文件在同一文件夹即可,特别注意onmessage解析的两层 parse

        WebSocket Test        

WebSocket Test

点击发送

4.测试示例


相关推荐:

PHP中Socket简单使用方法

PHP中Socket服务器搭建和测试方法教程

ChatX翻译
ChatX翻译

最实用、可靠的社交类实时翻译工具。 支持全球主流的20+款社交软件的聊天应用,全球200+语言随意切换。 让您彻底告别复制粘贴的翻译模式,与世界各地高效连接!

下载

详解php实现socket推送技术

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

php

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

php网站源码教程大全
php网站源码教程大全

本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

4

2025.12.31

视频文件格式
视频文件格式

本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

不受国内限制的浏览器大全
不受国内限制的浏览器大全

想找真正自由、无限制的上网体验?本合集精选2025年最开放、隐私强、访问无阻的浏览器App,涵盖Tor、Brave、Via、X浏览器、Mullvad等高自由度工具。支持自定义搜索引擎、广告拦截、隐身模式及全球网站无障碍访问,部分更具备防追踪、去谷歌化、双内核切换等高级功能。无论日常浏览、隐私保护还是突破地域限制,总有一款适合你!

7

2025.12.31

出现404解决方法大全
出现404解决方法大全

本专题整合了404错误解决方法大全,阅读专题下面的文章了解更多详细内容。

42

2025.12.31

html5怎么播放视频
html5怎么播放视频

想让网页流畅播放视频?本合集详解HTML5视频播放核心方法!涵盖<video>标签基础用法、多格式兼容(MP4/WebM/OGV)、自定义播放控件、响应式适配及常见浏览器兼容问题解决方案。无需插件,纯前端实现高清视频嵌入,助你快速打造现代化网页视频体验。

4

2025.12.31

关闭win10系统自动更新教程大全
关闭win10系统自动更新教程大全

本专题整合了关闭win10系统自动更新教程大全,阅读专题下面的文章了解更多详细内容。

3

2025.12.31

阻止电脑自动安装软件教程
阻止电脑自动安装软件教程

本专题整合了阻止电脑自动安装软件教程,阅读专题下面的文章了解更多详细教程。

3

2025.12.31

html5怎么使用
html5怎么使用

想快速上手HTML5开发?本合集为你整理最实用的HTML5使用指南!涵盖HTML5基础语法、主流框架(如Bootstrap、Vue、React)集成方法,以及无需安装、直接在线编辑运行的平台推荐(如CodePen、JSFiddle)。无论你是新手还是进阶开发者,都能轻松掌握HTML5网页制作、响应式布局与交互功能开发,零配置开启高效前端编程之旅!

2

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
进程与SOCKET
进程与SOCKET

共6课时 | 0.3万人学习

golang socket 编程
golang socket 编程

共2课时 | 0.1万人学习

swoole入门物联网开发与实战
swoole入门物联网开发与实战

共15课时 | 1.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号