一开始会接触这个php的socket是因为需要用到长连接,去搜一下php的socket。还真的有这个东西。于是就各种看资料,基本摸清了是怎么样的一个情况了。在这里我先描述一下,在上具体的代码。
php的socket通讯呢。是基于TCP上的。有个服务端创建了tcp的连接,然后客户端可以和服务端云运行的那个连接进行通讯。而服务端可以监听到客户端的请求,如发送信息。服务端这个时候也可以再响应数据回去。还是要实践一下才比较熟悉
上php的文档:http://php.net/manual/zh/ref.sockets.php
然后开始先写一个服务端的代码
service.php
<?php /** * Created by PhpStorm. * User: LiuJiaJun * Date: 2017/7/26 * Time: 10:56 */ $host = '127.0.0.1';//ip地址,这里是本地的 $port ='2008';//端口号 $sock = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);//创建一个socket,还不能用 if($sock < 0){ echo "socket_create() 失败的原因".socket_strerror(socket_last_error($sock)); } //将地址和端口绑定到刚创建的socket中 if($bind = socket_bind($sock,$host,$port)<0){ echo "socket_create() 失败的原因".socket_strerror(socket_last_error($bind)); } //进行监听,设置的数量是4个 if($listen = socket_listen($sock,4) <0){ echo "socket_create() 失败的原因".socket_strerror(socket_last_error($listen)); } $count = 5;//设置五次访问次数 do{ $accept = socket_accept($sock);//另一个Socket来处理通信 if($accept<0){ echo "socket_accept()失败的原因".socket_strerror(socket_last_error($accept)); break; }else{ $buf = socket_read($accept,8192);//读取客户端传送的数据 $response='you send message is:'.$buf; //将信息返回给客户端,第三个参数是返回的长度 $res = socket_write($accept,$response,strlen($response)); if($res !==false){ echo 'send message to client is successful'; } if($count--<=0){ break; } } socket_close($accept); }while(true); socket_close($sock);
再此说明一下,这个service.php文件应该是通过命令行的形式运行,即php service.php start。如果php命令不可以用,那么就需要在环境变量path那边配置一些你的php信息。先运行service.php,再去访问client.php文件。服务端接受5次请求就会自动关闭,代码上已经实现。
client.php客户端的程序
<?php /** * Created by PhpStorm. * User: LiuJiaJun * Date: 2017/7/26 * Time: 11:13 */ error_reporting(E_ALL); set_time_limit(0); $host = '127.0.0.1'; $port = '2008'; $socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP); if ($socket < 0) { echo "socket_create() failed: reason: " . socket_strerror($socket) . "\n"; } $result = socket_connect($socket, $host, $port);//连接服务端创建的接口 if ($result < 0) { echo "socket_connect() failed.\nReason: ($result) " . socket_strerror($result) . "\n"; }else { echo "连接 '$host' 端口 '$port'.'成功'.\n"; } $input = 'hello world'; if(!socket_write($socket, $input, strlen($input))) {//向服务端写数据 echo "socket_write() failed: reason: " . socket_strerror($socket) . "\n"; }else { echo "发送到服务器信息的内容为".$input; } while($output = socket_read($socket, 8192)) {//读取服务端响应的数据 echo "接受的内容为:",$output; } socket_close($socket); echo "关闭成功\n";
说明一下,client.php可以在网页上运行,只要能解释通php语言就行,但是这个例子也只能做到,你给他发送数据了,它在响应你一个数据,要是这样的话,和寻常的http请求没啥区别。当然也就是针对这个例子来说,我也是尝试用,还不能写出主动发送数据的代码。而且对有些函数还是了解甚少。
服务端运行截图:
客户端运行截图:
当然写到这里就是简单的知道一些socket函数的用法,以及他们之间的通讯而已。有了这些基础就能进一步钻研啦。
关于长连接的有些框架可以使用:
Swoole扩展:
附上官网地址:http://www.swoole.com/
附上文档地址:https://wiki.swoole.com/
Workman框架:
附上官网地址:http://www.workerman.net/
附上文档地址:https://www.kancloud.cn/walkor/workerman/315110
近段时间有用workman写一些东西,有时间的话在写一篇关于这个的文章吧
socket相关函数:
----------------------------------------------------------------------------------------------
socket_accept() 接受一个Socket连接
socket_bind() 把socket绑定在一个IP地址和端口上
socket_clear_error() 清除socket的错误或者最后的错误代码
socket_close() 关闭一个socket资源
socket_connect() 开始一个socket连接
socket_create_listen() 在指定端口打开一个socket监听
socket_create_pair() 产生一对没有区别的socket到一个数组里
socket_create() 产生一个socket,相当于产生一个socket的数据结构
socket_get_option() 获取socket选项
socket_getpeername() 获取远程类似主机的ip地址
socket_getsockname() 获取本地socket的ip地址
socket_iovec_add() 添加一个新的向量到一个分散/聚合的数组
socket_iovec_alloc() 这个函数创建一个能够发送接收读写的iovec数据结构
socket_iovec_delete() 删除一个已经分配的iovec
socket_iovec_fetch() 返回指定的iovec资源的数据
socket_iovec_free() 释放一个iovec资源
socket_iovec_set() 设置iovec的数据新值
socket_last_error() 获取当前socket的最后错误代码
socket_listen() 监听由指定socket的所有连接
socket_read() 读取指定长度的数据
socket_readv() 读取从分散/聚合数组过来的数据
socket_recv() 从socket里结束数据到缓存
socket_recvfrom() 接受数据从指定的socket,如果没有指定则默认当前socket
socket_recvmsg() 从iovec里接受消息
socket_select() 多路选择
socket_send() 这个函数发送数据到已连接的socket
socket_sendmsg() 发送消息到socket
socket_sendto() 发送消息到指定地址的socket
socket_set_block() 在socket里设置为块模式
socket_set_nonblock() socket里设置为非块模式
socket_set_option() 设置socket选项
socket_shutdown() 这个函数允许你关闭读、写、或者指定的socket
socket_strerror() 返回指定错误号的详细错误
socket_write() 写数据到socket缓存
socket_writev() 写数据到分散/聚合数组
本文参考了:http://www.jb51.net/article/66023.htm的文章,且本人水平有限,不足之处还望海涵。