欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

用php进行socket通讯

程序员文章站 2022-03-03 10:19:11
...

一开始会接触这个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请求没啥区别。当然也就是针对这个例子来说,我也是尝试用,还不能写出主动发送数据的代码。而且对有些函数还是了解甚少。

服务端运行截图:

用php进行socket通讯

客户端运行截图:

用php进行socket通讯

当然写到这里就是简单的知道一些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的文章,且本人水平有限,不足之处还望海涵。