我花了几个小时阅读TCP服务器以及我想要实现的所需协议,最后让一切都运行得很好。我注意到代码看起来像绝对的bollocks(正确的用法?我不是英国人),并希望得到一些优化它的反馈,主要是为了重用和可读性。
数据包格式总是int,int,int,string,string。
try
{
BinaryReader reader = new BinaryReader(clientStream);
int packetsize = reader.ReadInt32();
int requestid = reader.ReadInt32();
int serverdata = reader.ReadInt32();
Console.WriteLine("Packet Size: {0} RequestID: {1} ServerData: {2}", packetsize, requestid, serverdata);
List<byte> str = new List<byte>();
byte nextByte = reader.ReadByte();
while (nextByte != 0)
{
str.Add(nextByte);
nextByte = reader.ReadByte();
}
// Password Sent to be Authenticated
string string1 = Encoding.UTF8.GetString(str.ToArray());
str.Clear();
nextByte = reader.ReadByte();
while (nextByte != 0)
{
str.Add(nextByte);
nextByte = reader.ReadByte();
}
// NULL string
string string2 = Encoding.UTF8.GetString(str.ToArray());
Console.WriteLine("String1: {0} String2: {1}", string1, string2);
// Reply to Authentication Request
MemoryStream stream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(stream);
writer.Write((int)(1)); // Packet Size
writer.Write((int)(requestid)); // Mirror RequestID if Authenticated, -1 if Failed
byte[] buffer = stream.ToArray();
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
}
我将处理其他数据包类型,它们的格式相同(int / int / int / str / str),但值不同。我可能会创建一个数据包类,但这有点超出了我对如何将其应用于此场景的知识范围。如果它有所不同,这就是我正在实施的协议。
http://developer.valvesoftware.com/wiki/Source_RCON_Protocol
答案 0 :(得分:3)
思想:
答案 1 :(得分:0)
跳出来的第一件事就是始终将using statement与任何实现 IDisposable 的对象一起使用。这将确保即使在发生异常时也能妥善处理您的对象。
private void FillList(BinaryReader reader, List list)
{
while (reader.PeekChar() != -1)
{
list.Add(reader.ReadByte());
}
}
...
try
{
int packetsize, requestid, serverdata;
string string1, string2;
List<byte> str = new List<byte>();
using (BinaryReader reader = new BinaryReader(clientStream))
{
packetsize = reader.ReadInt32();
requestid = reader.ReadInt32();
serverdata = reader.ReadInt32();
Console.WriteLine("Packet Size: {0} RequestID: {1} ServerData: {2}", packetsize, requestid, serverdata);
FillList(reader, str);
// Password Sent to be Authenticated
string1 = Encoding.UTF8.GetString(str.ToArray());
str.Clear();
FillList(reader, str);
}
// NULL string
string2 = Encoding.UTF8.GetString(str.ToArray());
Console.WriteLine("String1: {0} String2: {1}", string1, string2);
// Reply to Authentication Request
using (MemoryStream stream = new MemoryStream())
using (BinaryWriter writer = new BinaryWriter(stream))
{
writer.Write((int)(1)); // Packet Size
writer.Write((int)(requestid)); // Mirror RequestID if Authenticated, -1 if Failed
byte[] buffer = stream.ToArray();
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
}
}