您现在的位置: 万盛学电脑网 >> 程序编程 >> 网络编程 >> php编程 >> 正文

PHP SOCKET编程详解

作者:佚名    责任编辑:admin    更新时间:2022-06-22

   这篇文章主要介绍了PHP SOCKET编程详解,需要的朋友可以参考下

  1. 预备知识

  一直以来很少看到有多少人使用php的socket模块来做一些事情,大概大家都把它定位在脚本语言的范畴内吧,但是其实php的socket模块可以做很多事情,包括做ftplist,http post提交,smtp提交,组包并进行特殊报文的交互(如smpp协议),whois查询。这些都是比较常见的查询。

  特别是php的socket扩展库可以做的事情简直不会比c差多少。

  php的socket连接函数

  1、集成于内核的socket

  这个系列的函数仅仅只能做主动连接无法实现端口监听相关的功能。而且在4.3.0之前所有socket连接只能工作在阻塞模式下。

  此系列函数包括

  fsockopen,pfsockopen

  这两个函数的具体信息可以查询php.net的用户手册

  他们均会返回一个资源编号对于这个资源可以使用几乎所有对文件操作的函数对其进行操作如fgets(),fwrite(), fclose()等单注意的是所有函数遵循这些函数面对网络信息流时的规律,例如:

  fread() 从文件指针 handle 读取最多 length 个字节。 该函数在读取完 length 个字节数,或到达 EOF 的时候,或(对于网络流)当一个包可用时就会停止读取文件,视乎先碰到哪种情况。

  可以看出对于网络流就必须注意取到的是一个完整的包就停止。

  2、php扩展模块带有的socket功能。

  php4.x 以后有这么一个模块extension=php_sockets.dll,Linux上是一个extension=php_sockets.so。

  当打开这个此模块以后就意味着php拥有了强大的socket功能,包括listen端口,阻塞及非阻塞模式的切换,multi-client 交互式处理等

  这个系列的函数列表参看http://www.php.net/manual/en/ref.sockets.php

  看过这个列表觉得是不是非常丰富呢?不过非常遗憾这个模块还非常年轻还有很多地方不成熟,相关的参考文档也非常少:(

  我也正在研究中,因此暂时不具体讨论它,仅给大家一个参考文章

  http://www.zend.com/pecl/tutorials/sockets.php

  2. 使用PHP socket扩展

  服务器端代码:

  ?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 <?php /** * File name server.php * 服务器端代码 * * @author guisu.huang * @since 2012-04-11 * */   //确保在连接客户端时不会超时 set_time_limit(0); //设置IP和端口号 $address = "127.0.0.1"; $port = 2046; //调试的时候,可以多换端口来测试程序! /** * 创建一个SOCKET * AF_INET=是ipv4 如果用ipv6,则参数为 AF_INET6 * SOCK_STREAM为socket的tcp类型,如果是UDP则使用SOCK_DGRAM */ $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("socket_create() 失败的原因是:" . socket_strerror(socket_last_error()) . "/n"); //阻塞模式 socket_set_block($sock) or die("socket_set_block() 失败的原因是:" . socket_strerror(socket_last_error()) . "/n"); //绑定到socket端口 $result = socket_bind($sock, $address, $port) or die("socket_bind() 失败的原因是:" . socket_strerror(socket_last_error()) . "/n"); //开始监听 $result = socket_listen($sock, 4) or die("socket_listen() 失败的原因是:" . socket_strerror(socket_last_error()) . "/n"); echo "OKnBinding the socket on $address:$port ... "; echo "OKnNow ready to accept connections.nListening on the socket ... n"; do { // never stop the daemon //它接收连接请求并调用一个子连接Socket来处理客户端和服务器间的信息 $msgsock = socket_accept($sock) or die("socket_accept() failed: reason: " . socket_strerror(socket_last_error()) . "/n");   //读取客户端数据 echo "Read client data n"; //socket_read函数会一直读取客户端数据,直到遇见n,t或者字符.PHP脚本把这写字符看做是输入的结束符. $buf = socket_read($msgsock, 8192); echo "Received msg: $buf n";   //数据传送 向客户端写入返回结果 $msg = "welcome n"; socket_write($msgsock, $msg, strlen($msg)) or die("socket_write() failed: reason: " . socket_strerror(socket_last_error()) ."/n"); //一旦输出被返回到客户端,父/子socket都应通过socket_close($msgsock)函数来终止 socket_close($msgsock); } while (true); socket_close($sock);

  客户端代码:

  ?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <?php /** * File name:client.php * 客户端代码 * * @author guisu.huang * @since 2012-04-11 */ set_time_limit(0);   $host = "127.0.0.1"; $port = 2046; $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)or die("Could not create socketn"); // 创建一个Socket   $connection = socket_connect($socket, $host, $port) or die("Could not connet servern"); // 连接 socket_write($socket, "hello socket") or die("Write failedn"); // 数据传送 向服务器发送消息 while ($buff = socket_read($socket, 1024, PHP_NORMAL_READ)) { echo("Response was:" . $buff . "n"); } socket_close($socket);

  使用cli方式启动server:

  php server.php

  这里注意socket_read函数:

  可选的类型参数是一个命名的常数:

  PHP_BINARY_READ - 使用系统recv()函数。用于读取二进制数据的安全。 (在PHP>“默认= 4.1.0)

  PHP_NORMAL_READ - 读停在 n或r(在PHP <= 4.0.6默认)

  针对参数PHP_NORMAL_READ ,如果服务器的响应结果没有 n。造成socket_read(): unable to read from socket

  3. PHP socket内部源码

  从PHP内部源码来看,PHP提供的socket编程是在socket,bind,listen等函数外添加了一个层,让其更加简单和方便调用。但是一些业务逻辑的程序还是需要程序员自己去实现。

  下面我们以socket_create的源码实现来说明PHP的内部实现。

  前面我们有说到php的socket是以扩展的方式实现的。在源码的ext目录,我们找到sockets目录。这个目录存放了PHP对于socket的实现。直接搜索PHP_FUNCTION(socket_create),在sockets.c文件中找到了此函数的实现。如下所示代码:

  ?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21