`
aslijiasheng
  • 浏览: 58429 次
  • 性别: 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 ...

    udp_UDP_php_

    在PHP中实现UDP通信,可以使用内置的socket函数库,这为开发者提供了与底层网络通信的能力。本教程将详细介绍如何使用PHP进行UDP通信,并通过一个简单的客户端示例来说明。 首先,理解UDP的特点至关重要。UDP不提供...

    linux c语言和php通信代码UDP

    ### Linux C语言与PHP通过UDP协议进行通信 #### 背景介绍 在现代软件开发中,不同编程语言之间的通信是非常常见的需求。本案例展示了一个简单的C语言服务器(server.c)与PHP客户端(client.php)之间如何通过用户...

    PHP的Socket通信之UDP通信实例

    总结来说,PHP通过Socket API可以方便地实现UDP通信。服务器端通过`stream_socket_server`创建UDP套接字,监听特定端口,然后用`stream_socket_recvfrom`接收客户端消息,处理后使用`stream_socket_sendto`回应。...

    TCP实现P2P通信、TCP穿越NAT的方法、TCP打洞源码

    TCP打洞,也称为UDP打洞或NAT打洞,是一种让两个处于NAT后的设备直接通信的技术。TCP打洞通常分为两种类型:被动模式和主动模式。在被动模式中,设备A首先尝试连接到设备B,B接收连接后,向A的公网IP和端口发送数据...

    php 淘宝udp

    在PHP中处理UDP通信,开发者通常会使用socket编程。PHP提供了socket扩展,通过这个扩展,我们可以创建、绑定、监听和发送/接收UDP数据包。在淘宝的SDK中,可能封装了这些底层的socket操作,提供了一套更易于使用的...

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

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

    PHP的Socket通信

    2. **标准化**:通过Socket,开发者可以使用统一的方式来访问不同的网络协议,如TCP和UDP等。 3. **简化开发**:Socket使得开发人员无需深入理解底层协议细节即可实现网络通信功能。 #### Socket与TCP/UDP的关系 ...

    UDP.rar_PHP UDP

    在PHP中实现UDP通信,通常会用到socket编程,这允许程序通过网络发送和接收数据。 在"PHP UDP"这个项目中,开发者可能已经实现了一个简单的网络聊天软件,它基于UDP协议进行数据交换。UDP聊天应用的基本功能可能...

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

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

    基于UDP协议的网络摄像头的设计与实现

    与TCP相比,UDP不保证数据包的顺序、可靠性、不提供数据重传机制,但其优点在于传输效率较高,适合于对实时性要求较高的应用场景,如视频流的传输。 2.视频采集:在网络摄像头的设计中,首先需要完成视频信号的采集...

    PHP Socket Udp实时在线云消费机服务器端源码.rar

    在PHP中,`socket`函数库提供了一系列的API,用于创建、连接和操作套接字,从而实现TCP或UDP等网络协议的通信。 UDP(User Datagram Protocol)是一种无连接的、不可靠的传输协议,相比TCP,它更注重速度,适用于...

    【免费】网络通信TCP聊天室源代码可群聊通信加密

    聊天室是一种多人实时通信的应用,通常基于TCP或UDP协议实现。在这个案例中,TCP被选择是因为它能提供可靠的数据传输服务,适合需要保证消息不丢失和有序到达的聊天应用。聊天室的设计通常包括用户注册、登录、发送...

    PHP语言实现基于tcpip协议的Server端和client实现互相通信+原理讲解.docx

    PHP 使用 `socket` 函数库实现了基于 TCP/IP 协议的 Server 端和 Client 端通信。Server 端创建并绑定 Socket,监听客户端连接,接收并响应数据;Client 端创建 Socket,连接 Server,发送数据并接收响应。TCP/IP ...

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

    Swoole框架的核心特性在于其对异步编程的支持,使得PHP可以处理TCP、UDP网络通信以及WebSocket服务,甚至包括HTTP服务器和任务调度。下面我们将详细探讨Swoole在PHP异步通信中的应用。 **1. TCP服务器** 在Swoole...

    TCP-IP技术大全.zip

    TCP/IP技术大全是一个涵盖网络通信基础到高级应用的综合学习资源,主要针对互联网协议栈的核心——TCP/IP协议族进行深入探讨。在这个压缩包中,我们很可能会找到一系列关于TCP/IP的详细章节,包括但不限于概念解释、...

    基于PHP的ESFramework之P2P通信Demophp版源码.zip

    2. **连接建立**:TCP或UDP协议可以用来在P2P节点之间建立通信链路。PHP的socket编程接口提供了创建、监听和管理套接字连接的能力。 3. **数据传输**:一旦连接建立,节点间的数据交换是通过发送和接收数据包进行的...

    php5 实现socket 通信

    它为应用程序提供了访问低层传输协议的能力,比如 TCP 和 UDP。在 PHP5 中,Socket 的功能是通过内置的 `socket` 扩展来实现的。 #### 二、Socket 创建与绑定 1. **创建 Socket:** ```php $commonProtocol = ...

    PHP_swoole

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

Global site tag (gtag.js) - Google Analytics