多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# PHP 简单TCP通信实现原理 ### socket的关键函数: 客户端: socket_create() 作用:创建一个socket套接字,也就是建立通讯节点。会话懂不懂,你打电话的隧道、 socket_connect() 作用:连接一个套接字, 开始一个socket连接,连接对端,你打电话是不是需要输入对方手机号? socket_write() 作用:把数据写入套接字中,你打电话是不是有事情和对面说? socket_read() 作用:读取服务端返回来的套接流信息,你给他说事情了,对面是不是要会话,当然如果你是舔狗,那就是另外一种情况了。 服务端: 1.创建socket (没隧道怎么打电话咧) socket_create() 2.绑定socket (给自己搞个地址,谁都能打进来,纯海王) socket_bind($socket,'127.0.0.1',8888)//绑定接收的套接流主机和端口,与客户端相对应 3.监听 (这个是真海外,谁打过来都是第一时间接通,看样子当海外也是很辛苦的) socket_listen($socket,4)//监听套接流 ## 实现 首先需要现有一个 tcp 服务端 ~~~ <?php //创建socket套接字 $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); //设置阻塞模式 socket_set_block($socket); //为套接字绑定ip和端口 socket_bind($socket,'127.0.0.1',3046); //监听socket socket_listen($socket,4); while(true) { //接收客户端请求 if(($msgsocket = socket_accept($socket)) !== false) { //读取请求内容 $buf = socket_read($msgsocket, 8192); echo "Received msg: $buf \n"; $str = "this is a service message"; //向连接的客户端发送数据 socket_write($msgsocket, $str,strlen($str)); //操作完之后需要关闭该连接否则 feof() 函数无法正确识别打开的句柄是否读取完成 socket_close($msgsocket); } } ~~~ ## 连接 tcp 服务端客户端: 使用 socket 系列函数连接 ~~~ <?php $st="socket send message"; $length = strlen($st); //创建tcp套接字 $socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP); //连接tcp socket_connect($socket, '127.0.0.1',3046); //向打开的套集字写入数据(发送数据) $s = socket_write($socket, $st, $length); //从套接字中获取服务器发送来的数据 $msg = socket_read($socket,8190); echo $msg; //关闭连接 socket_close($socket); ~~~ 使用 fsockopen 连接 ~~~ <?php //使用 fsockopen 打开tcp连接句柄 $fp = fsockopen("tcp://127.0.0.1",3046); $msg = "fsockopen send message"; //向句柄中写入数据 fwrite($fp,$msg); $ret = ""; //循环遍历获取句柄中的数据,其中 feof() 判断文件指针是否指到文件末尾 while (!feof($fp)){ stream_set_timeout($fp, 2); $ret .= fgets($fp, 128); } //关闭句柄 fclose($fp); echo $ret; ~~~ 使用 stream_socket_client 连接 ~~~ <?php //使用 stream_socket_client 打开 tcp 连接 $fp = stream_socket_client("tcp://127.0.0.1:3046"); $msg = "fsockopen send message"; //向句柄中写入数据 fwrite($fp,$msg); $ret = ""; //循环遍历获取句柄中的数据,其中 feof() 判断文件指针是否指到文件末尾 while (!feof($fp)){ stream_set_timeout($fp, 2); $ret .= fgets($fp, 128); } //关闭句柄 fclose($fp); echo $ret; ~~~