// 创建套接字
socket_create();
// 绑定
socket_bind();
// 监听
socket_listen(); // 主体, 死循环
while(true){
// select模型, 取出可读套接字列表
socket_select(); foreach(sockets) {
// 如果是监听连接请求端口的套接字
if(is listensocket) {
// 接受请求
socket_accept();
}
else {
// 读取封包
socket­_recv();
// 处理用户动作 {问题就在这}
process();
}
}
}
php socket 模型及效率问题
呼呼安

呼呼安
// 创建套接字
socket_create();
// 绑定
socket_bind();
// 监听
socket_listen(); // 主体, 死循环
while(true){
// select模型, 取出可读套接字列表
socket_select(); foreach(sockets) {
// 如果是监听连接请求端口的套接字
if(is listensocket) {
// 接受请求
socket_accept();
}
else {
// 读取封包
socket­_recv();
// 处理用户动作 {问题就在这}
process();
}
}
} 关于php做服务端的效率, 我想这里是个问题吧。
在每处理一个用户的动作的时候, 整个循环被阻塞在这里, 导致其他的连接不能接受, 其他用户的动作请求不能被处理。 直到process()函数返回才能处理下一个动作。
处理一个用户动作的时候, 可能还要涉及到数据库访问等, 可能比较耗时。
不知道有没有哪位大仙有解决办法呢。 我想的是, 如果能做一个动作队列, 这里的循环只负责接收数据, 然后把数据包保存在一个队列里, 就去接收下一个用户的封包。
另一个线程(不知道PHP怎么实现线程, 或是能不能实现)从队列中抽取每一个用户的动作请求来处理它。。 或着process()函数能不能做成非阻塞的, 让它可以立即返回。。 小弟初学,如有可笑之处,请见谅! 评论 () • 分享 • 链接 • -- 
4个答案 票 数
冯义军

冯义军14.02K
最佳答案
这个问题我也遇到过到,比如打开两个终端,telnet socket服务端,如果其中一个不返回,另一个终端总是等待。最后使用fork子进程方式解决,大概代码如下,你可以参考下: 死循环部分 do {
$msgsock = socket_accept($socket);
$pid = pcntl_fork();
if($pid == -) {
// fork error ;
}else if($pid) {
socket_close($msgsock);
}else {
$buf = socket_read($msgsock,,PHP_NORMAL_READ);
$ret = func($buf); //调用函数处理接收到的内容
socket_write($msgsock,$ret,strlen($ret));
socket_close($msgsock);
//posix_kill(posix_getpid(),0);
exit();
}
}while(true) 评论 () • 链接 • -- @冯义军 你好, 我在本地测试的时候, 可以用cmd运行php, 或是在网页上访问一下, 然后关闭网页就行了, php会一直执行, 然后端口就可以一直访问。。
但是我放服务器上(linux), 怎么让它一直执行啊, 我用网页访问它的时候可以连接, 如果关了网页, 就会关闭。 – 呼呼安 -- @呼呼安 在 socket服务端程序中 开头增加 ignore_user_abort(); set_time_limit(); 这两句,就可以运行一次关浏览器了。
另外还可以在命令行运行,如 /usr/local/php/bin xxx.php & – 冯义军 -- @冯义军 set_time_limit()这个我加了, ignore_user_abort();这个没加就不行吗 – 呼呼安 -- @呼呼安 ignore_user_abort();主要是设置与客户机断开是否会终止脚本的行,set_time_limit() 主要是指定程序运行的最大时间。 – 冯义军 --
显示更多隐藏的评论
呼呼安

呼呼安70
我貌似自己想到了一个办法。。 process()的地方修改一下, 直接写到数据库里(或着谁有更快的方法请告知)。
就是我所说的“动作队列”。 再写一个类似的php文件, 也是死循环。
while(true) {
// 从数据库里取出一条待处理动作
// 处理它
// 从数据库里删除该动作
} 甚至可以多运行几次这个文件, 就是不知道想停的时候怎么停 >_< 评论 () • 链接 • --
龙虾猫

龙虾猫1
风大做了一个基于pcntl的多进程Socket服务框架,可以参考使用下
http://code.google.com/p/mpass/

最新文章

  1. nginx 隐藏版本信息
  2. iOS学习之视图控制器
  3. Integer自动装箱分析
  4. 重新看php数组
  5. ARCGIS接口详细说明
  6. 你真的了解如何将 Nginx 配置为Web服务器吗
  7. How to resolve CSRF protection error while adding service through Ambari api
  8. Keepalived配置详解
  9. 2018年-2019年第二学期第六周C#学习个人总结
  10. \n和\r区别
  11. gradle tool升级到3.0注意事项
  12. charles https抓包 (安卓安装证书)
  13. 在JavaScript中什么时候使用==是正确的?
  14. java JDK JRE 1.6,1.7,1.8各个版本版本下载链接
  15. 17个CSS知识点整理
  16. (转)小议TCP的MSS(最大分段)以及MTU
  17. centos 7 keepalived故障邮件通知实战(附Python邮件发送脚本)
  18. 错误“AxImp.exe”已退出,代码为 -1163019603【转载及个人看法】
  19. com.sun.image.codec.jpeg在Eclipse中报错的解决办法
  20. 智能客服 利用python运行java代码

热门文章

  1. Android内存优化7 内存检测工具1 Memory Monitor检测内存泄露
  2. easyui datagrid 表格动态隐藏部分列的展示
  3. iOS:CYLTabBarController的具体使用实例:实现新浪微博的主流框架
  4. 利用PMKID破解PSK的实际测试与影响评估
  5. longest-repeating-character-replacement(难)
  6. 一步一步学RenderMonkey(5)--渲染到纹理(RTT) 【转】
  7. Maven Web项目配置Mybatis
  8. linux经常使用文字处理命令总结
  9. 【甘道夫】Win7环境下Eclipse连接Hadoop2.2.0
  10. FEC