Подключение к исходному игровому серверу в VB.NET - PullRequest
1 голос
/ 10 ноября 2009

Я разрабатываю приложение, которое обнаруживает исходные игры, работающие в локальной сети.Следуя спецификациям , предоставленным Valve , я сузил его до именно того, что я хочу: сделать UDP-соединение на порту 27015, отправив запрос A2S_INFO (0xFFFFFFFF, за которым следует "TSource Engine Query")и синтаксический анализ двоичного ответа.

Это код, с которым я работаю:

Dim sIP As String = "192.168.0.154"
Dim nPort As Integer = 27015

Dim connectionMessage As String = "ÿÿÿÿTSource Engine Query" & Chr(0)

Dim endPoint As New IPEndPoint(IPAddress.Parse(sIP), nPort)

Dim client As Socket = New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 6000)
client.SendTo(Encoding.ASCII.GetBytes(connectionMessage), endPoint)
Console.WriteLine("Message sent to " & sIP & ":" & nPort & vbCrLf & connectionMessage)
Dim sBuffer(1400) As Byte
Try
    client.ReceiveFrom(sBuffer, endPoint)
    MsgBox(System.Text.Encoding.Unicode.GetString(sBuffer))
Catch ex As SocketException
    MsgBox("Failed to receive response on " & sIP & ":" & nPort & ":" & vbCrLf & ex.Message)
End Try

Я получаю SocketError.TimedOut исключений, сообщая мне:

Не удалось получить ответ на 192.168.0.154:27015: Попытка подключения не удалась, поскольку подключенная сторона не ответила должным образом через некоторое время, или не удалось установить соединение, так как подключенный хост не смог ответить

Я вполне уверен, что это очень близко к ответу, потому что следующая очень простая версия PHP работает как шарм:

$ip = "192.168.0.154";
$port = 27015;

$fp = fsockopen("udp://".$ip,$port, $errno, $errstr);
socket_set_timeout($fp, 6);

$prefix = "\xff\xff\xff\xff";
$command = "TSource Engine Query";
$msg = "$prefix$command";
fputs($fp, $msg, strlen($msg));

$response = "";
do {
    $response .= fgets($fp, 16);
    $status = socket_get_status($fp);
} while ($status['unread_bytes']);
fclose ($fp);

echo $response;

Это дает мне ответ в соответствии со спецификациями.

Я близок, но что-то не так с моим кодом VB.NET.Что я делаю не так?

Решение

Тип кодировки недопустим для передачи двоичных данных.Я заменил следующее:

Encoding.ASCII.GetBytes(connectionMessage)

на:

System.Text.Encoding.[Default].GetBytes(connectionMessage)

И это было немедленно решено.

Более надежное решение, предложенное "pub", может бытьуказать кодовую страницу (хотя я не проверял это):

Encoding.GetEncoding("iso-8859-1").GetBytes(connectionMessage)

Ответы [ 3 ]

2 голосов
/ 20 мая 2010

Для тех парней по всему миру, у которых кодовая страница iso-8859-1 не установлена ​​на компьютере по умолчанию, используйте:

Encoding.GetEncoding ( "ISO-8859-1"). GetBytes (connectionMessage)

1 голос
/ 10 ноября 2009

Вы смотрели на эту Браузер многопоточных игровых серверов в VB.Net на CodeProject? Если вы не хотите повторно использовать уже написанный код, я уверен, что вы можете проверить, как они это сделали, чтобы увидеть, можете ли вы найти свою проблему.

Надеюсь, что помогает, мир.

1 голос
/ 10 ноября 2009

Вместо открытия сокета попробуйте http://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...