`
aslijiasheng
  • 浏览: 57084 次
  • 性别: 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
分享到:
评论

相关推荐

    组成原理课程实验:MIPS 流水线CPU、实现36条指令、转发、冒险检测-内含源码和说明书.zip

    组成原理课程实验:MIPS 流水线CPU、实现36条指令、转发、冒险检测-内含源码和说明书.zip

    setuptools-50.0.2-py3-none-any.whl

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    setuptools-1.1.6.tar.gz

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    CEA二次开发脚本:用于ECSP配比设计

    CEA二次开发脚本:用于ECSP配比设计

    环形数组是一种特殊的数据结构

    环形数组

    什么是环形数组以及学习环形数组的意义是什么

    环形数组

    母亲节祝福 Python 代码(包含详细介绍)

    附件是母亲节祝福 Python 代码(包含详细介绍),文件绿色安全,请大家放心下载,仅供交流学习使用,无任何商业目的!

    setuptools-0.7.4.zip

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    max111111111

    max111111111

    攻防世界问题的概要介绍与分析

    "攻防世界"这一术语广泛应用于网络安全领域,它生动描绘了一个持续演进的技术战场,其中攻击者与防御者围绕着数据保护、系统安全及网络基础设施的完整性展开激烈的智斗。在这个虚拟而又现实交织的舞台上,知识、技能与创新成为了决定胜负的关键要素。以下是对这个复杂多维攻防世界的深度资源描述: 在一个由代码编织的宇宙里,"攻防世界"不仅是一场技术较量,更是对策略、耐心与适应能力的考验。想象一个庞大的数字迷宫,其中数据如同珍贵的宝藏,被各式各样的防火墙、加密协议和安全系统重重保护。而另一边,潜伏着一群技艺高超的黑客,他们利用漏洞、社会工程学以及先进的攻击手段,试图穿透这些防线,揭露系统的脆弱之处。 对于防御方而言,构建坚不可摧的安全体系是永恒的目标。这要求他们精通最新的安全技术,如入侵检测系统(IDS)、安全信息和事件管理(SIEM)平台、以及人工智能驱动的威胁狩猎工具。同时,定期进行渗透测试和红蓝对抗演练,模拟真实攻击场景,以发现并修补潜在漏洞。此外,培养安全意识,教育员工识别钓鱼邮件、恶意软件等,也是构建第一道防线的重要环节。 攻击者一方,则聚焦于不断探索未知漏洞(零日漏洞)、开发定制化恶意软

    关于java出租车计价器设计与实现.zip

    关于java出租车计价器设计与实现 总共4个模块 (1)出租车计价系统可以实现出租车信息的管理。 1.1出租车信息的查询:通过数据库查询出租车的车型,车号,以及是否可用 1.2出租车信息的增加:向数据库中添加出租车的车型,车号,以及是否可用 1.3出租车信息的修改:对数据库中已经存在的出租车的车型,车号,以及是否可用的信息进行修改 1.4出租车信息的删除:删除数据库中已经存储的出租车的信息 (2)出租车计价系统可以实现司机信息的管理。 2.1司机信息的查询:通过数据库查询出司机的年龄,性别,学历,名字等信息 2.2司机信息的增加:向数据库中添加司机的年龄,性别,学历,名字等信息 2.3司机信息的修改:对数据库中已经存在的司机的年龄,性别,学历,名字等信息进行修改 2.4司机信息的删除:删除数据库中已经存储的司机的信息 (3)出租车计价系统可以实现出租车计价功能。 3.1通过java多线程,模拟出租车在路上的情景 3.2通过距离计费的方式,将订单的时间,乘客的信息,订单的价格等插入数据库中 (4)出租车计价系统可以实

    华为OD机试D卷 - 拼接URL - 免费看解析和代码.html

    私信博主免费获取真题解析以及代码

    setuptools-8.2.tar.gz

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    C语言输出母亲节祝福(内含详细描述)

    附件是C语言输出母亲节祝福(内含详细描述),文件绿色安全,请大家放心下载,仅供交流学习使用,无任何商业目的!

    setuptools-40.4.2.zip

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    仰卧起坐YOLOV8-POSE,C++

    仰卧起坐YOLOV8-POSE,C++,只需要OPENCV

    行动学习指导手册glq.ppt

    行动学习指导手册glq.ppt

    setuptools-0.9.8.tar.gz

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    计算机网络资料复习pdf

    计算机网络资料复习pdf

    setuptools-1.0.zip

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

Global site tag (gtag.js) - Google Analytics