ホームページ >バックエンド開発 >PHPチュートリアル >PHP中Sockets与流有什么关系啊!!!!!
在哪些情况下我们会用到这么高级的东西?尤其是关于流的。在哪些情况下会用流这种东西?建立长连接不是说PHP不允许吗???那么PHP出现这些东西,到底是用在哪些场合呢?
在哪些情况下我们会用到这么高级的东西?尤其是关于流的。在哪些情况下会用流这种东西?建立长连接不是说PHP不允许吗???那么PHP出现这些东西,到底是用在哪些场合呢?
php不能使用长连接,主要原因是这门语言是不能常驻内存的(除非你在命令行下使用php),你请求一个php写的网页,然后刷新一下,上次请求过程中产生的所有局部变量都被标记为回收了。想想,如果使用长连接,你肯定要复用之前建立连接的socket句柄吧,正是由于这种机制造成没法保存这个socket句柄了。
不知道你说的 stream 是指什么?二进制流的话用到的地方也挺多的吧,文件传输基本上都是用的二进制传输的吧,另外我记得微信开放接口的传输也是使用的二进制的。这个问题我不是很清楚,就稍带讲一下不多表了。
我觉得你肯定理解错长连接是什么东西了。说到长连接我们必须说一下短连接。HTTP连接 是一种无状态连接,client 和 server 在三次握手建立连接之后,client 请求数据,server 返回数据后就会关闭连接,这种就是短连接。基于短连接的原理,我们在 client 使用 AJAX 不停的向服务器请求是否有新数据(即 AJAX pull)的行为就是轮询。这种方法优点在于简单,缺点当然也很明显,造成了相当多不必要的资源浪费以及服务器的无上压力。
为了解决这些问题,出现了基于短连接方法的修改版 - 长连接。长连接的方法也很简单,client 和 server 在三次握手建立连接,client 请求数据,当 server 端发现没有新数据的时候并不立即返回,而是hold住连接(即 Keep Alive),带有新数据返回 / 连接超时的时候则返回数据关闭连接。基于长连接的原理,当 client 收到数据返回(即连接断开)之后我们立即发起一次新的连接重复以上过程的方法就是我们所说的 长轮询 了。长连接比短连接的好处在于大大减少了 client 和 server 的请求次数。众所周知,一次 HTTP连接 需要经历三次握手这种复杂的过程,光速从美国经过海底光纤到达中国还需要 50ms 左右的时间呢,何况还要经历三次!所以这种方法的好处是很明显的,但是有好的一面也会有坏的一面。长连接由于需要服务器 hold 住连接,当 client 请求多的时候必然会对服务器造成 ++无上 的压力,这个压力并没有解决。
根据问题我再说一下 server 端 hold 住连接这个事情。众所周知,PHP当页面脚本执行完毕之后就会将内容返回给 CGI 然后交给 web server 返回给 client 端。所以 hold住连接这件事情也就非常简单,写一个死循环让脚本一直在运行即可 hold住连接了。PHP 对于这个的实现还是比较简单的,我在这里写一个语义 demo 仅供参考:
<code><?php set_time_limit(0); do { $data = getNewData(); if( count($data) > 0 ) { echo json_encode($data); break; } sleep(5); } while(true); ?> </code>
使用长连接的时候记得 client 端发起请求的时候最好设置一个连接超时时间,当超过时间之后即断开链接,通过缩短超时时间可以达到控制服务器压力的目的,当超时时间过小的时候基本上就和轮询没有区别了。
长连接和 socket 是没有什么关系的,现在我们来说说 socket。 socket 在 OSI网络七层协议中是介于应用层和传输层之间的东西,可以做基于 TCP, UDP, RawIP 和链路层的 socket(转自 网络篇详解)。具体的关于 HTTP链接 和 socket 的区别的话可以看看我刚才的引文,里面有较为详细的描述。不过简单来说就是 sockets 能模拟以 TCP/UDP 等为基础做的应用层的链接。
OSI中的层 | 功能 | TCP/IP协议族 |
---|---|---|
应用层 | 文件传输,电子邮件,文件服务,虚拟终端 | TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet |
表示层 | 数据格式化,代码转换,数据加密 | 没有协议 |
会话层 | 解除或建立与别的接点的联系 | 没有协议 |
传输层 | 提供端对端的接口 | TCP,UDP |
网络层 | 为数据包选择路由 | IP,ICMP,RIP,OSPF,BGP,IGMP |
数据链路层 | 传输有地址的帧以及错误检测功能 | SLIP,CSLIP,PPP,ARP,RARP,MTU |
物理层 | 以二进制数据形式在物理媒体上传输数据 | ISO2110,IEEE802。IEEE802.2 |
--- 转载自 OSI网络七层协议和四层协议
那么 PHP到底可不可以做 socket 呢?答案是 可以的!毕竟是 世界上最美丽的语言 嘛!基于图灵完备的理论也的确是这样子的。在 PHP 中有专门的 socket 实现扩展:Sockets。但是大家说 PHP不可以 也不是错的。因为 PHP 的 socket 实现中由一个重要的步骤是使用 socket_listen() 函数实现端口的监听,这个就必须需要 CLI 的支持了。总所周知 PHP一般的应用是使用 CGI 在网页端实现,所以基于 CGI 上 PHP 的确是不可以的。但是 PHP 又不是没有 CLI,哼哼~
在你想HTTP又没有curl扩展的时候。