尝试解码UDP消息,它是一个128字节的数组,第一个可变长度字符串从第7个字节开始。我想要做的是将数组拆分为单个元素,并根据类型(字节,字符串)解码每个元素。数据格式/类型在此处定义:http://developer.valvesoftware.com/wiki/Server_queries#Goldsource_servers_2
这是原始数据。 接收缓冲区:255 255 255 255 73 48 115 99 52 46 120 32 84 101 115 116 32 83 101 114 118 101 114 91 50 56 49 51 93 0 99 48 97 48 101 0 115 118 101 110 99 111 111 112 5 2 0 83 118 101 110 32 67 111 45 111 112 32 52 46 54 32 111 114 32 108 97 116 101 114 0 70 0 0 12 0 100 119 0 0 49 46 49 46 50 46 49 0 145 145 105 3 44 67 175 180 9 64 1 70 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
这是在“0x00”上分割的字符串数组的样子。 字符串响应:???? I0sc4.x测试服务器[2813] c0a0e svencoop4 Sven Co-op 4.6或更高版本F♀dw1.1.2.1 ?? i♥,C ?? @☺F
这适用于第五个元素(单词“later”之后的“F”)。之后事情变得有点乱,我无法弄清楚如何选择/解码剩余的元素。
# convert to string.
$StringResponse = [Text.Encoding]::ASCII.GetString($ReceiveBuffer)
# make an array of strings.
$SplitString = $StringResponse.split([char][byte]"0x00")
# store the value of individual elements.
$servername_split = $SplitString[0].split([char]"0")
$Map = $SplitString[1]
$gamedirectory = $SplitString[2]
$gamedescription = $SplitString[3]
$appid = [byte][char]$splitstring[4]
使用原始数据:
这可以在四个字节的标题255,255,255,255之后访问前几个字节元素。然后变量长度字符串开始。
$type = [char]$ReceiveBuffer[4]
$NetworkProtocolVersion = $ReceiveBuffer[5]
所以我不能这样做来访问原始数据末尾附近的字节元素,除非我事先知道变量长度字符串数据使用了多少字节。
$numplayers = $ReceiveBuffer[72]
$maxnumplayers = $ReceiveBuffer[73]
$numbots = $ReceiveBuffer[74]
$dedicated = [char]$ReceiveBuffer[75]
$os = [char]$ReceiveBuffer[76]
$passwordreq = $ReceiveBuffer[77]
$secure = $ReceiveBuffer[78]
控制台输出:
Type: I
Network Protocol Version: 48
Server Name: sc4.x Test Server[2813]
Map: c0a0e
Game Directory: svencoop4
Game Description: Sven Co-op 4.6 or later
AppID: 70
TIA,
答案 0 :(得分:0)
# Receive Buffer size varies from server to server.
$ReceiveBuffer = New-Object Byte[] 128
# Info Reply
$BytesReceived = 0
Try
{
$BytesReceived = $UdpSocket.Receivefrom($ReceiveBuffer, [REF]$UdpSocket.LocalEndpoint)
}
# An Exception will be thrown if the server is down or hung.
Catch [Net.Sockets.SocketException]
{
# Set Flag
$Script:NoConnectionTimeOut = $False
}
# Verify and Decode HLDS server response.
If ($BytesReceived -gt 0)
{
# Ignore the four byte header and store the values of the first two bytes.
$type = [char]$ReceiveBuffer[4]
$netversion = $ReceiveBuffer[5]
# Loop through the byte array and store each type of data.
$i = 0
$StringNum = 0
$FoundAppID = $False
foreach ($element in $receivebuffer)
{
If ($i -gt 5 -and $i -lt 80)
{
If ($element -ne 0)
{
$string = $string + [Text.Encoding]::ASCII.GetString($element)
}
Else
{
$StringNum++
if ($stringnum -eq 1) { $ServerName = $string }
if ($stringnum -eq 2) { $MapName = $string }
if ($stringnum -eq 3) { $InfoGameDir = $string }
if ($stringnum -eq 4) { $GameDescription = $string }
$string = ""
}
}
if ($i -gt 50 -and $element -eq 70 -and $FoundAppID -eq $False)
{
if ($element -eq 70)
{
$FoundAppID = $True
$AppID = $element;$arrayIndex = $i
$i++;$i++
$numplayers = $ReceiveBuffer[$i]
$i++
$maxnumplayers = $ReceiveBuffer[$i]
$i++
$numbots = $ReceiveBuffer[$i]
$i++
$dedicated = [char]$ReceiveBuffer[$i]
$i++
$os = [char]$ReceiveBuffer[$i]
$i++
$Password = $ReceiveBuffer[$i]
$i++
$Secure = $ReceiveBuffer[$i]
for ($j = 1; $j -lt 9; $j++)
{
$i++
$GameVersion = $GameVersion + [Text.Encoding]::ASCII.GetString($ReceiveBuffer[$i])
}
$i++
$EDF = $ReceiveBuffer[$i]
}
}
$i++
}
# Write the server info.
write-host "`n Type: $type"
write-host " Protocol Version: $netversion"
write-host " Server Name: $ServerName"
write-host " Map: $MapName"
write-host " Game Directory: $InfoGameDir"
write-host " Game Description: $GameDescription"
write-host " AppID: $AppID, $arrayIndex"
write-host " Number of players: $numplayers"
write-host " Maximum players: $maxnumplayers"
write-host " Number of bots: $numbots"
write-host " Dedicated: $dedicated"
write-host " OS: $os"
write-host " Password: $Password"
write-host " Secure: $Secure"
write-host " Game Version: $GameVersion"
write-host " EDF: $EDF"
#"Raw Data: $ReceiveBuffer"