我正在try 编写一个PHPTCP客户端来连接到虚幻引擎5的RCON服务器.我正在使用GitHub上的一个现有C#项目作为参考,但我在准备要发送的包时遇到了问题.GitHub项目准备一个byte数组,然后将其发送到服务器.我曾try 用PHP重写该函数,但我不确定是否做得正确.但更大的问题是,socket_write()socket_send()fwrite()都想要string分,而我现在有array分.我相信我可以将我的数组格式化为字符串,以使用pack()表示字节,但我不确定如何使用.

这是https://github.com/Sp1rit/ArkRcon/blob/master/Rcon/RconPacket.cs中的C#函数,这显示了我需要发送的内容.

    public static implicit operator byte[](RconPacket packet)
    {
        byte[] buffer = new byte[packet.Size + 4];

        packet.Size.ToLittleEndian().CopyTo(buffer, 0);
        packet.Id.ToLittleEndian().CopyTo(buffer, 4);
        ((int)packet.Type).ToLittleEndian().CopyTo(buffer, 8);
        Encoding.ASCII.GetBytes(packet.Body).CopyTo(buffer, 12);

        return buffer;
    }

以下是我对此进行转换的try (参见下面的ConvertToArray()).我用了__invoke,但也有一个反向函数,它不允许我使用__invoke两次.我提供了整个类,这样您就可以看到完整的画面,还可以看到一些注释代码,其中我try 了不同的方法.

class RconPacket
{

    private static int $idCounter = 1;

    public $Id;
    public int $Type;
    public $Body;

    public function GetSize()
    {
        return (!empty($Body) ? strlen($Body) + 10 : 0);
    }

    public function __construct($type, $body)
    {
        $this->Id = RconPacket::$idCounter++;
        $this->Type = $type;
        $this->Body = $body;
    }

    public function ConvertToArray(): array
    {
        $buffer = array(); //array_fill(0, $this->GetSize() + 4, 0);
        $buffer[] = pack('V', $this->GetSize() + 4); //->copy($buffer, 0);
        $buffer[] = pack('V', $this->Id); //->copy($buffer, 4);
        $buffer[] = pack('V', (int)$this->Type); //->copy($buffer, 8);
        $buffer = array_merge($buffer, array_map(fn($c) => ord($c), str_split($this->Body)));
    
        //$buffer[] = str_split($this->Body)->map(fn($c, $i) => ord($c)); //->copy($buffer, 12);

        return $buffer;
    }

    public static function ConvertToRconPacket(string $data): RconPacket
    {
        $size = unpack('V', $data)[1];
        $id = unpack('V', $data, 4)[1];
        $type = unpack('V', $data, 8)[1];
        $body = substr($data, 12, $size - 10);

        return new RconPacket($id, $type, $body);
    }
}

我try 使用pack("a", $buffer);将数组转换为字符串,但pack()也需要string

推荐答案

基本知识:PHP中的string实际上是一个二进制数组(例如,$str[3]是第4个字节),所以你不必使用PHP数组,你可以使用pack函数打包的字符串.

$data = pack('V3a*',
             $this->GetSize(),
             $this->Id,
             (int)$this->Type,
             $this->Body);
fwrite($fp, $data);

Php相关问答推荐

Laravel 11发送邮箱时奇怪的未定义数组键名称

编写WooCommerce多步骤签出

如果WooCommerce中存在特定的运输方式,则隐藏其他运输方式

在WooCommerce产品中按类型对产品属性术语进行分类以供显示

在WooCommerce中设置带有国家/地区和年份前缀的顺序序号

将数组推送到数组时,数组推送()出现问题

移动应用:在PHP中忽略Cookie?

根据发货类别在WooCommerce产品页面中显示快捷代码

htaccess重命名index.php以在URL中显示为SEO的友好名称

PHP SimpleXML:按属性值访问 node

根据页面以及是否在促销,向 WooCommerce 中显示的价格添加前缀

使用 Spomky Labs JWT 框架中的 verifyWithKey 验证 id_token JWT 的签名需要 30 秒以上

PHP:数组的等边

在 WooCommerce 管理变量产品中启用其他变体图像

加载 Xdebug PHP 7.4.0 失败

WooCommerce 订单和邮箱通知的自定义产品描述

将Shopware 6后端中定义的值导入MultiFilter

php-http/discovery 插件 1.15.1 是否仍在使用自己的模块 destruct Contao 4.13 中的composer 安装?

WordPress 函数 get_post(post_id) 是否查询数据库?

如何在 Laravel 9 中判断异常是否可报告?