《 swooleThinkphp 》TCP 服务器 【 八 】



UDP 服务器




UDP 协议与 TCP 协议属同一层的网络协议,相比 TCP 协议而言,UDP 协议则轻巧了许多,UDP 协议是一个高效且不可信的传输协议,因为 UDP 协议只管发送数据,无法得知数据是否传输成功。当数据传输环境特别可靠(如内网环境)或者数据丢失部分也可以接受,并且无法容忍延时。则推荐使用 UDP 协议。


接下来我们演示一下如何用 ThinkPHP5 和 Swoole 来构架一个 UDP 服务器


创建 ThinkPHP5 自定义命令行

1.创建命令行类

创建application/console/UdpServer.php文件


<?php

namespace app\Console;


use think\console\Command;
use think\console\Input;
use think\console\Output;

class UdpServer extends Command
{
    protected $server;
    // 命令行配置函数
    protected function configure()
    {
        // setName 设置命令行名称
        // setDescription 设置命令行描述
        $this->setName('udp:start')->setDescription('Start UDP Server!');
    }
    // 设置命令返回信息
    protected function execute(Input $input, Output $output)
    {
        $this->server = new \swoole_server("127.0.0.1", 9502, SWOOLE_PROCESS, SWOOLE_SOCK_UDP);
        // 设置 server 运行前各项参数
        $this->server->set([
            'worker_num' => 4,
            'daemonize'  => false,
        ]);
        // 注册回调函数
        $this->server->on('Start', [$this, 'onStart']);
        $this->server->on('Packet', [$this, 'onPacket']);
        $this->server->on('Close', [$this, 'onClose']);
        // 启动服务器
        $this->server->start();
    }
    // 主进程启动时回调函数
    public function onStart(\swoole_server $server)
    {
        echo "Start\n";
    }
    // 接受数据回调
    public function onPacket(\swoole_server $server, $data, $clientInfo)
    {
        $server->sendto($clientInfo['address'], $clientInfo['port'], "Server " . $data);
        var_dump($data);
        var_dump($clientInfo);
    }
    // 关闭连时回调函数
    public function onClose(\swoole_server $server, $fd, $from_id)
    {
        echo "Close\n";
    }
}


UDP 服务器和 TCP 服务器 不同,UDP 协议没有连接的概念。启动服务器后,客户端无需连接,所以 UDP 服务器没有 Connect 回调函数,直接可以向服务器监听的 9502 端口发送数据包。需要注意的是 UDP 服务器接受数据的事件为 onPacket,TCP 服务器接受数据的事件为 onReceive。


2.修改配置文件

文件所在 application/command.php


<?php

return [
    'app\console\UdpServer',
];


接下来就可以通过命令行来启动 UDP 服务器


$ > php think udp:start

确保 UDP 服务器正常启动后,我们简单改造一下之前的同步 TCP 客户端,来用 Swoole 自己实现一个 UDP 客户端来想 UDP 服务器发送数据


<?php

// 实例化同步阻塞 UDP 客户端
$client = new \swoole_client(SWOOLE_SOCK_UDP, SWOOLE_SOCK_SYNC);

// 建立连接,连接失败时停止程序
$client->connect('127.0.0.1', 9502) or die("connect failed\n");

// 向 UDP 服务器发送数据
$client->send('111');
echo "ok";


把 TCP 客户端修改成 UDP 客户端只需要把SWOOLE_SOCK_TCP修改为SWOOLE_SOCK_UDP,并且删除掉返回接受数据函数即可

在浏览器中访问后得到ok后,确定向服务器发送数据成功,接下来我们查看服务器返回结果



返回结果中正确的返回了,客户端向服务器发送的内容,同时显示出客户端的相关信息