在一天中的大部分时间里,我一直在抨击我的代码,我完全被难倒了。基本上,源游戏引擎有一个文档协议的RCON(网络远程控制台?),我试图重现。有数百个示例,但所有这些示例都来自客户端(建立与游戏服务器的RCON的连接),因为我正在尝试重新创建服务器部分以回复客户端。
以下是有关RCON协议的信息。我对代码的问题是,当我收到身份验证请求时,一切都很好。当我尝试回复它并且没有连接时,连接失败。所以我在回复时做错了但不确定是什么。
http://developer.valvesoftware.com/wiki/Source_RCON_Protocol
private void ReadClientPacket(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
while (true)
{
try
{
int packetsize;
// Create a new Packet Object and fill out the data from the incoming TCP Packets
RCONPacket packet = new RCONPacket();
using (BinaryReader reader = new BinaryReader(clientStream))
{
// First Int32 is Packet Size
packetsize = reader.ReadInt32();
packet.RequestId = reader.ReadInt32();
packet.RconDataReceived = (RCONPacket.RCONDATA_rec)reader.ReadInt32();
Console.WriteLine("Packet Size: {0} RequestID: {1} ServerData: {2}", packetsize, packet.RequestId, packet.RconDataReceived);
// Read first and second String in the Packet (UTF8 Null Terminated)
packet.String1 = ReadBytesString(reader);
packet.String2 = ReadBytesString(reader);
Console.WriteLine("String1: {0} String2: {1}", packet.String1, packet.String2);
switch (packet.RconDataReceived)
{
case RCONPacket.RCONDATA_rec.SERVERDATA_AUTH:
{
ReplyAuthRequest(packet.RequestId, tcpClient);
break;
}
case RCONPacket.RCONDATA_rec.SERVERDATA_EXECCOMMAND:
{
//ReplyExecCommand(packet.RequestId, tcpClient);
break;
}
default:
{
break;
}
}
}
break;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
break;
}
}
tcpClient.Close();
}
private void ReplyAuthRequest(int RequestID, TcpClient client)
{
Console.WriteLine("Replying to Auth Request");
// Authentication Reply
using (NetworkStream clientStream = client.GetStream())
using (MemoryStream stream = new MemoryStream())
using (BinaryWriter writer = new BinaryWriter(stream))
{
writer.Write((int)10); // Packet Size
writer.Write(RequestID); // Mirror RequestID if Authenticated, -1 if Failed
writer.Write((int)RCONPacket.RCONDATA_sent.SERVERDATA_AUTH_RESPONSE);
writer.Write(ConvertStringToByteArray("" + char.MinValue));
writer.Write(ConvertStringToByteArray("" + char.MinValue));
byte[] buffer = stream.ToArray();
Console.WriteLine("size of full auth response packet is {0}", buffer.Length);
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
}
}
答案 0 :(得分:0)
您是否一直在使用Wireshark?
当您尝试复制/反向设计现有协议时,此工具至关重要。只需使用已知工作的客户端进行正常身份验证并保存日志即可。然后使用您自己的代码,尝试查看线路上发送的位与日志中的位不同。
有时通过查看代码就可以看到非常困难的事情,例如'\ n'插入错误的点,或者在整个消息之后添加一行
答案 1 :(得分:0)
我前段时间遇到过类似问题
在你的回复功能中:
using (NetworkStream clientStream = client.GetStream())
(...)
clientStream的处理可能是罪魁祸首。在我的情况下,流的处理导致连接终止,GetStream()不返回流的新实例,它返回TCPClient拥有的Stream。看看是否有帮助。