php socket 模型及效率问题
2024-08-29 03:46:44
// 创建套接字
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/
最新文章
- nginx 隐藏版本信息
- iOS学习之视图控制器
- Integer自动装箱分析
- 重新看php数组
- ARCGIS接口详细说明
- 你真的了解如何将 Nginx 配置为Web服务器吗
- How to resolve CSRF protection error while adding service through Ambari api
- Keepalived配置详解
- 2018年-2019年第二学期第六周C#学习个人总结
- \n和\r区别
- gradle tool升级到3.0注意事项
- charles https抓包 (安卓安装证书)
- 在JavaScript中什么时候使用==是正确的?
- java JDK JRE 1.6,1.7,1.8各个版本版本下载链接
- 17个CSS知识点整理
- (转)小议TCP的MSS(最大分段)以及MTU
- centos 7 keepalived故障邮件通知实战(附Python邮件发送脚本)
- 错误“AxImp.exe”已退出,代码为 -1163019603【转载及个人看法】
- com.sun.image.codec.jpeg在Eclipse中报错的解决办法
- 智能客服 利用python运行java代码
热门文章
- Android内存优化7 内存检测工具1 Memory Monitor检测内存泄露
- easyui datagrid 表格动态隐藏部分列的展示
- iOS:CYLTabBarController的具体使用实例:实现新浪微博的主流框架
- 利用PMKID破解PSK的实际测试与影响评估
- longest-repeating-character-replacement(难)
- 一步一步学RenderMonkey(5)--渲染到纹理(RTT) 【转】
- Maven Web项目配置Mybatis
- linux经常使用文字处理命令总结
- 【甘道夫】Win7环境下Eclipse连接Hadoop2.2.0
- FEC