博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PHP中使用socket通信响应速度慢的原因与解决办法
阅读量:6572 次
发布时间:2019-06-24

本文共 3103 字,大约阅读时间需要 10 分钟。

在PHP中作为客户端与服务器端使用socket进行通信时,一般我们使用fsockopen,但在使用这个函数进行通信时,有时候发现数据的反应时间特别长,更有甚者能达到1分钟。以下是代码片段:

1 
url, $this->port, $errno, $errstr, 10); 7 8 if (!$fp) { 9 return null;10 } else {11 fputs($fp, $this->method." ".$this->uri." HTTP/1.1\r\n");12 fputs($fp, "Host: ".$this->url.":".$this->port."\r\n");13 fputs($fp, "Content-type: text/html;charset=".$this->charset."\r\n");14 fputs($fp, "Accept-Language: zh-cn\r\n");15 fputs($fp, "User-Agent: Mozilla/4.0(Compatible win32; MSIE)\r\n");16 fputs($fp, "Content-Length: ".strlen($data)."\r\n");17 fputs($fp, "Connection: close\r\n\r\n");18 fputs($fp, $data);19 20 while(!feof($fp)) {21 $result .= fgets($fp, 1024);22 }23 24 fclose($fp);25 26 $arr = split("\r\n", $result);27 $state = split(" ", $arr[0]);28 29 if (substr($state[1], 0, 1) != 2) {30 return null;31 } else {32 return substr($result, strpos($result, "\r\n\r\n") + 4);33 }34 }35 }

上面这段代码就会有时候出现数据响应时间特别长。经过调试发现问题出在fgets这个函数的返回上,最后一次数据返回的时间很长,说是数据返回不如说是服务器端因为超时断开了连接。经过查阅手册会发现,关于fgets的返回的条件为:碰到换行符(包括在返回值中)、EOF 或者已经读取了 length - 1 字节后停止(看先碰到那一种情况)。

问题就出在服务器端缓冲会话的时候是不会返回结束标志,也不返回换行符的情况。那么我们可以通过以下方法来解决这个问题。

设置一个返回长度$length = 1024。第一次时使用这个长度,当有数据返回时,取出数据的长度$len,然后根据返回的数据来计算还有多少剩余的数据,这样就可以根据$length与(剩余的长度+1)找出最小值$min。下次fgets时的返回长度修正为$min。这样就可以正常的判断返回数据的大小。部分代码如下:

1 
url, $this->port, $errno, $errstr, 10); 6 7 if (!$fp) { 8 return null; 9 } else {10 fputs($fp, $this->method." ".$this->uri." HTTP/1.1\r\n");11 fputs($fp, "Host: ".$this->url.":".$this->port."\r\n");12 fputs($fp, "Content-type: text/html;charset=".$this->charset."\r\n");13 fputs($fp, "Accept-Language: zh-cn\r\n");14 fputs($fp, "User-Agent: Mozilla/4.0(Compatible win32; MSIE)\r\n");15 fputs($fp, "Content-Length: ".strlen($data)."\r\n");16 fputs($fp, "Connection: close\r\n\r\n");17 fputs($fp, $data);18 19 $len = -1;20 $length = 1024;21 while(!feof($fp)) {22 $result .= fgets($fp, $length);23 24 if (stripos($result, "\r\n\r\n") !== false) {25 $start = stripos($result, "Content-Length:") + 15;26 27 if ($start !== false && $len < 0) {28 $end = stripos($result, "\r\n", $start);29 $len = trim(substr($result, $start, stripos($result, "\r\n", $start) - $start));30 }31 32 if ($len > 0) {33 $str = substr($result, strpos($result, "\r\n\r\n") + 4);34 $length = min($length, $len - strlen($str) + 1);35 }36 37 if ($length < 2) {38 fclose($fp);39 return $str;40 }41 }42 }43 }44 }

转载于:https://www.cnblogs.com/AUOONG/archive/2012/11/30/2796090.html

你可能感兴趣的文章
为什么 ++[[]][+[]]+[+[]] = 10?
查看>>
ContentProvider
查看>>
Redis 持久化存储
查看>>
Android 自定义GridView网格布局
查看>>
基于 jQuery & CSS3 实现智能提示输入框光标位置
查看>>
我的友情链接
查看>>
ThreadLocal分析
查看>>
mysql优化:连接数
查看>>
如何优化js代码(1)——字符串的拼接
查看>>
PHP 时间操作 / 跳转问题
查看>>
Windows 2012 R2 FSMO角色相关小记录
查看>>
(小蚂蚁站长吧)网站优化做好这八步你就是seo第一
查看>>
使用流的方式往页面前台输出图片
查看>>
java核心技术反射
查看>>
我的友情链接
查看>>
Maven创建新的依赖项目
查看>>
2015年10月26日作业
查看>>
LAMP,安装脚本
查看>>
Java异常总结
查看>>
DHCP
查看>>