zoukankan      html  css  js  c++  java
  • php的socket通信

     socket通常叫做‘套接字’,用于描述IP地址和端口,是一个通信链的句柄。应用程序通过套接字向网络发出请求或者应答忘了请求。socket既不是程序,也不是协议,其只是操作系统提供的通信层的一组抽象API。

    通信需要服务端和客户端组成:

    服务端:

    使用php初始化socket然后绑定一个端口,对端口进行监听。调用accept阻塞,等待客户端连接。

    客户端:

    客户端初始化一个socket,然后连接服务器,如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。

    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() 写数据到分散/聚合数组

    案例:

    服务端

    <?php
    set_time_limit(0); //限制执行时间  0为不限制
    $ip = '127.0.0.1';
    $port = 8001;//端口
    
    /**
    socket通信整个过程 
    socket_create  //创建一个套接字
    socket_bind  //给套接字绑定 ip 和端口
    socket_listen //监听套接字上的连接
    socket_accept //接受一个socket连接
    socket_read //接收客户端 发送的数据
    socket_write //将数据写到 socket 缓存 向客户端发送
    socket_close   //关闭套接字资源
    */ 
    
    if(($sock = socket_create(AF_INET,SOCK_STREAM,SOL_TCP)) < 0) {
        echo "socket_create() 失败的原因是:".socket_strerror($sock)."
    ";
    }
    
    if(($ret = socket_bind($sock,$ip,$port)) < 0) {
        echo "socket_bind() 失败的原因是:".socket_strerror($ret)."
    ";
    }
    
    if(($ret = socket_listen($sock,4)) < 0) {
        echo "socket_listen() 失败的原因是:".socket_strerror($ret)."
    ";
    }
    
    $count = 0;
    
    do {
        if (($msgsock = socket_accept($sock)) < 0) {
            echo "socket_accept() failed: reason: " . socket_strerror($msgsock) . "
    ";
            break;
        } else {
            
            //发到客户端
            $msg ="测试成功!
    ";
            socket_write($msgsock, $msg, strlen($msg));
            
            echo "测试成功了啊
    ";
            $buf = socket_read($msgsock,8192);
            
            
            $talkback = "收到的信息:$buf
    ";
            echo $talkback;
            
            if(++$count >= 5){
                break;
            };
            
        
        }
        //echo $buf;
        socket_close($msgsock);
    
    } while (true);
    
    socket_close($sock);
    ?>

    运行php 文件

    运行后 应该看不见结果  可以使用 

    netstat -ntlp 查看 8001 端口是否被占用

     客户端:

    <?php
    error_reporting(E_ALL);
    set_time_limit(0);
    echo "socket通信客户端
    ";
    $port = 8001;//端口
    $ip = "127.0.0.1";//ip
    
    /**
    socket连接整个过程
     socket_create //建立一个socket 连接
     socket_connect // 开始一个socket连接  连接服务端
     socket_write //将数据写入缓存   向服务端发送
     socket_read// 读取服务端的结果
     socket_close // 关闭套接字资源
      */
    
    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    if ($socket < 0) {
        echo "socket_create() failed: reason: " . socket_strerror($socket) . "
    ";
    }else {
        echo "OK.
    ";
    }
    
    echo "试图连接 '$ip' 端口 '$port'...
    ";
    $result = socket_connect($socket, $ip, $port);
    if ($result < 0) {
        echo "socket_connect() failed.
    Reason: ($result) " . socket_strerror($result) . "
    ";
    }else {
        echo "连接OK
    ";
    }
    
    $in = "Ho
    first blood
    ";
    $out = '';
    
    if(!socket_write($socket, $in, strlen($in))) {
        echo "socket_write() failed: reason: " . socket_strerror($socket) . "
    ";
    }else {
        echo "发送到服务器信息成功!
    ";
        echo "发送的内容为:<font color='red'>$in</font> <br>";
    }
    
    while($out = socket_read($socket, 8192)) {
        echo "接收服务器回传信息成功!
    ";
        echo "接受的内容为:",$out;
    }
    
    
    echo "关闭SOCKET...
    ";
    socket_close($socket);
    echo "关闭OK
    ";
    ?>

    运行客户端得到结果:

    在看看服务端的窗口结果:

     PHP 语言的特性决定了php 在这方面它只适合做客户端,不适合做服务端。

  • 相关阅读:
    hdu 2485 Destroying the bus stations 迭代加深搜索
    hdu 2487 Ugly Windows 模拟
    hdu 2492 Ping pong 线段树
    hdu 1059 Dividing 多重背包
    hdu 3315 My Brute 费用流,费用最小且代价最小
    第四天 下载网络图片显示
    第三天 单元测试和数据库操作
    第二天 布局文件
    第一天 安卓简介
    Android 获取存储空间
  • 原文地址:https://www.cnblogs.com/phpshen/p/6118534.html
Copyright © 2011-2022 走看看