我正在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