找回密码
 注册账号

QQ登录

只需一步,快速开始

《泰拉瑞亚下载-1.4.2.3版》 泰拉瑞亚服务器 - MOD模组下载

入驻泰拉战网 新手指引 - 升级 - 师徒

泰拉瑞亚合成表 泰拉卡牌 - 泰拉江湖 - 泰拉刺客

联系泰拉开发组👈进入 积分市场 - 房产交易 - 水晶获取

查看: 2248|回复: 0

[原生PHP] PHP socket 编程: select同步非阻塞多路复用模式

[复制链接]

501

主题

18

回帖

5

广播

论坛版主

积分
258
泰拉
22
水晶
1
铜钥匙
0
银钥匙
0
金钥匙
0

【江湖新秀】【宝剑回鞘】【泰拉达人】【奥运选手】

发表于 2020-5-9 19:10:39 | 显示全部楼层 |阅读模式

php作为一个效率一般的单线程语言,用来做socket服务器确实有点勉强,不过php还是提供了各种相关函数,使其可以完整地实现socket编程的各项功能。


  1. // Create a new socket                  
  2. $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);                                    
  3. $server['host'] = '127.0.0.1';           
  4. $server['port'] = '2013';            
  5. socket_bind($socket,$server['host'],$server['port']);
  6. socket_listen($socket);
  7. ...
复制代码



首先需要生成一个服务器端socket,并绑定到某主机、端口。注意,一定要将该socket设为非阻塞的。否则socket在accept等待新连接时程序将会被阻塞.


  1. socket_set_nonblock($socket);
复制代码



一个socket服务端必然需要同时为多个客户端提供服务,单线程的php 的socket模块提供了select的多路复用模型来解决这一问题。


  1. //复制一份客户端列表,socket_select函数的引用参数
  2. $read = $this->clients;               
  3. while ( @socket_select($read, $write = NULL, $except = NULL,2) < $this->maxClient ) {            
  4. //从连接池中选取一个socket资源   
  5. $newc = $this->selectClient( $read,$socket );   
  6. if ( $newc === false )     
  7.      break ;                                                  
  8. ...
复制代码



当程序发现有一个新的客户端socket连接服务端时,就将该socket加入select的连接池,等待服务端提供服务,需要注意,加入的客户端socket也需要设为非阻塞,否则客户端在等待服务端读取其缓冲区中的数据时也会将线程阻塞。

当客户端发出退出信号时,服务端将该客户端socket从连接池中去除,socket连接断开。

完成编程后,可用telnet作为客户端对该服务端进行测试。

另外,依靠PHP 的 libevent 扩展(需配置安装),也可以实现 epoll/kqueue 的异步非阻塞I/O模型,性能上会表现的更加优秀。
[发帖际遇]: 君山 乐于助人,奖励 6 泰拉. 幸运榜 / 衰神榜
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

QQ|友链申请|Archiver|手机版|小黑屋|游芯沙盒 ( 陕ICP备11006283号-1 )

GMT+8, 2024-5-20 15:22 , Processed in 0.107557 second(s), 37 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表