`
aslijiasheng
  • 浏览: 57078 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

php tcp udp 通信

阅读更多
 /**
     * udp收发包
     * @param $ip
     * @param $port
     * @param $timeout
     * @return int 0-成功,非0-失败(具体参考类头部错误码常量定义)
     */
    private function udpSocket($ip, $port, $timeout)
    {
        $time = microtime(true);
        $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);

        if (false === $sock) {
            return self::UDL_SOCKET_CREATE_FAILED; // socket创建失败
        }

        if (!socket_set_nonblock($sock)) {
            return self::UDL_SOCKET_SET_NONBLOCK_FAILED; // 设置socket非阻塞失败
        }

        $len = strlen($this->mUdlRequestBuf);
        if (socket_sendto($sock, $this->mUdlRequestBuf, $len, 0x100, $ip, $port) != $len) {
            return self::UDL_SOCKET_SEND_FAILED; // socket发送失败
        }

        if (0 == $timeout) {
            return self::UDL_SUCCESS; // 无回包的情况,返回成功
        }

        $read = array($sock);
        $second = floor($timeout);
        $usecond = ($timeout - $second) * 1000000;
        $ret = socket_select($read, $write, $except, $second, $usecond);

        if (FALSE === $ret) {
            return self::UDL_SOCKET_RECEIVE_FAILED; // 收包失败
        } elseif ($ret != 1) {
            return self::UDL_SOCKET_SELECT_TIMEOUT; // 收包超时
        }

        $out = null;
        while (true) {
            if (microtime(true) - $time > $timeout) {
                return self::UDL_SOCKET_TIMEOUT; // 收包超时
            }

            // 32k:32768 = 1024 * 32
            $outLen = @socket_recvfrom($sock, $out, 32768, 0, $host, $port);
            if (!($outLen > 0 && $out != '')) {
                continue;
            }

            $list = unpack('Nseq', substr($out, 9, 4));
            $seq = $list['seq'];

            if ($seq !== $this->mSeq) {
                continue;
            }

            $this->mUdlResponseBuf = $out;

            return self::UDL_SUCCESS;
        }
    }

    /**
     * udp收发包
     * @param $ip
     * @param $port
     * @param $timeout
     * @return int 0-成功,非0-失败(具体参考类头部错误码常量定义)
     */
    private function tcpSocket($ip, $port, $timeout)
    {
        $time = microtime(true);
        $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

        if (false === $sock) {
            return self::UDL_SOCKET_CREATE_FAILED; // socket创建失败
        }

        if (!socket_connect($sock, $ip, $port)) {
            return self::UDL_SOCKET_CONNECT_FAILED;
        }

        $len = strlen($this->mUdlRequestBuf);
        if (socket_write($sock, $this->mUdlRequestBuf, $len) != $len) {
            return self::UDL_SOCKET_SEND_FAILED;
        }

        $read = array($sock);
        $ret = socket_select($read, $write = null, $except = null, $timeout);

        if (false === $ret) {
            return self::UDL_SOCKET_RECEIVE_FAILED;
        } elseif ($ret != 1) {
            return self::UDL_SOCKET_SELECT_TIMEOUT;
        }

        $totalLen = 0;
        while (true) {
            if (microtime(true) - $time > $timeout) {
                return self::UDL_SOCKET_TIMEOUT; // 收包超时
            }

            //读取最多32M的数据
            $data = socket_read($sock, self::SOCKET_TCP_MAX_PCK_SIZE, PHP_BINARY_READ);

            if (empty($data)) {
                // 已经断开连接
                return self::UDL_SOCKET_CLOSED;
            } else {
                //第一个包
                if ($this->mUdlResponseBuf === null) {
                    $this->mUdlResponseBuf = $data;

                    //在这里从第一个包中获取总包长
                    $list = unpack('Nlen', substr($data, 1, 4));
                    $totalLen = $list['len'];
                } else {
                    $this->mUdlResponseBuf .= $data;
                }

                //check if all package is receved
                if (strlen($this->mUdlResponseBuf) >= $totalLen) {
                    return self::UDL_SUCCESS;
                }
            }
        }
    }

    /**
     * 打包、收发包、解包
     * @param $ip
     * @param $port
     * @param int $timeout
     * @return int
     */
    private function sendAndReceive($ip, $port, $timeout = 2, $socketMode)
    {
        try {
            $this->serialize();

            if ($socketMode === self::SOCKET_MODE_UDP) {
                $r = $this->udpSocket($ip, $port, $timeout);
            } else {
                $r = $this->tcpSocket($ip, $port, $timeout);
            }

            if ($r !== self::UDL_SUCCESS) {
                return $r;
            }

            $this->unserialize();
        } catch (Exception $e) {
            return self::UDL_FAILED;
        }

        return self::UDL_SUCCESS;
    }

 

3
1
分享到:
评论

相关推荐

    php socket通信(tcp/udp)实例分析

    本文实例讲述了php socket通信(tcp/udp)方法。分享给大家供大家参考,具体如下: 注意 1.在socket_bind的时候ip地址不能真回环地址如127.0.0.1 2.server.php后台跑起来的时候nohup php server.php > /var/tmp/a.log ...

    针对Android公共基础功能封装的系列基础框架,包含日志系统、工具库、BLE通信库、UDP通信库、TCP通信库等。.zip

    网络与通信:数据传输、信号处理、网络协议、网络与通信硬件、网络安全网络与通信是一个非常广泛的领域,它涉及到计算机科学、电子工程、数学等多个学科的知识。 云计算与大数据:数据集、包括云计算平台、大数据...

    Swoole(PHP网络通信引擎) v2.0.5.zip

    Swoole是一个专门为PHP语言设计的异步、并行、高性能网络通信引擎,使用纯C语言编写,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,异步Redis,数据库连接池,AsyncTask,消息队列,毫秒...

    PHP的Socket通信

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

    PHP异步通信Swoole框架参考源码

    通过示例代码分别演示了对应的基于socket通信层的 TCP服务器、UDP服务器及Web服务器,异步及进程处理。

    PHP_swoole

    PHP语言的高性能网络通信框架,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,数据库连接池,AsyncTask,消息队列,毫秒定时器,异步文件读写,异步DNS查询。 Swoole可以广泛应用于互联网、...

    OHSCE (PHP通信框架) v0.1.27 Beta.zip

    对TCP、UDP、ICMP、RS232/485通信,可轻松驾驭各种以太网应用和工业总线应用。OHSCE科学的平衡了高性能和高可靠性,天生分布式支持,特别适合应用于对可靠性和稳定性有较高要求的场景。如:物联网、工业与自动化工程...

    PHP的异步并行高性能网络通信引擎使用纯C语言编写

    PHP的异步、并行、高性能网络通信引擎,使用纯C语言编写,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,异步Redis,数据库连接池,AsyncTask,消息队列,毫秒定时器,异步文件读写,异步DNS...

    详解php的socket通信

    对 TCP/IP 、 UDP 、 Socket 编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵。 那什么是TCP/IP、UDP? TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议...

    Swoole扩展

    PHP的异步、并行、高性能网络通信引擎,使用纯C语言编写,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,异步Redis,数据库连接池,AsyncTask,消息队列,毫秒定时器,异步文件读写,异步DNS...

    websocket聊天室.zip

    websocket聊天室 swoole-masterSwoole 使 PHP 开发人员可以编写高性能高并发的 TCP、UDP、Unix Socket、HTTP、 WebSocket 等服务,让 PHP 不再局限于 Web 领域。Swoole4 协程的成熟将 PHP 带入了前所未有的时期, 为...

    php项目-PHP网络数据包分析工具的设计与开发(源代码+论文).rar

    它支持多种网络接口和协议,包括TCP/IP、UDP、ICMP等,能够实时捕获和分析经过指定网络接口的数据包。同时,工具还提供了丰富的过滤选项,使用户可以根据需要精确地筛选出感兴趣的数据包。 除了基本的数据包捕获和...

    php7.0 swoole扩展

    使 PHP 开发人员可以编写高性能的异步并发 TCP、UDP、Unix Socket、HTTP,WebSocket 服务。Swoole 可以广泛应用于互联网、移动通信、企业软件、云计算、网络游戏、物联网(IOT)、车联网、智能家居等领域。 使用 PHP...

    深入浅出讲解:php的socket通信原理

    对TCP/IP、UDP、Socket编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵。那么我想问: 1. 什么是TCP/IP、UDP? 2. Socket在哪里呢? 3. Socket是什么呢? 4. 你会使用它们吗? 什么是...

    swoole 开发代码

    使 PHP 开发人员可以编写高性能的异步并发 TCP、UDP、Unix Socket、HTTP,WebSocket 服务。Swoole 可以广泛应用于互联网、移动通信、企业软件、云计算、网络游戏、物联网(IOT)、车联网、智能家居等领域。 使用 PHP...

    swoole-4.4.8.tgz

    Swoole是一个面向生产环境的 PHP 异步网络通信引擎,使 PHP 开发人员可以编写高性能的异步并发 TCP、UDP、Unix Socket、HTTP,WebSocket 服务

    一个很简单实用 的 swoole 框架 麻雀虽小, 五脏俱全.rar

    而swoole扩展是提供了更底层的服务器通信机制,可以使用UDP、TCP等协议,而不仅仅是http。 安装方式上也不一样,swoole扩展像其它PHP扩展一样安装,可以用pecl,也可以编译安装。而swoole框架用composer引入之后...

    php异步多线程swoole用法实例

    一般来说,Swoole提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,数据库连接池,AsyncTask,消息队列,毫秒定时器,异步文件读写,异步DNS查询. swoole以前听过, 拿来做游戏服务器简直是神器...

    Swoole异步并行和协程C扩展 v4.8.13

    Swoole框架是一个为PHP用C和C++编写的基于事件的高性能...同时也是PHP的异步、并行、高性能网络通信引擎,使用纯C语言编写,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,异步Redis,数据库连

Global site tag (gtag.js) - Google Analytics