繁体   English   中英

关于优化C#NET代码块的反馈

[英]Feedback on Optimizing C# NET Code Block

我只花了几个小时阅读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

思考:

  • 你不是真的使用读者,除了一些整数; 否则,你需要的只是ReadByte,你可以从Stream中做到这一点,并保存一些间接/混淆
  • 手动读取整数以避免Endianness问题
  • 逐字节读取可能很昂贵; 如果可能的话,尝试通过循环读取而不是ReadByte来填充缓冲区(或者更确切地说:读取正确数量的数据)
  • 如果多条消息在同一个管道中传输,则读取到EOF可能会失败(要么破坏数据,要么永久阻塞); 您通常需要终结符序列或长度前缀。 我更喜欢后者,因为它让你使用Read而不是ReadByte
  • 我假设你的例子中是packetSize; 使用它是至关重要的 :分离消息,验证您有完整的消息,以及拒绝过大的数据
  • 考虑async(BeginRead)是否合适 - 有时是,有时没有; 并注意这使得处理更加棘手,因为您不能使用“使用”与异步
  • 使用MemoryStream时,将.GetBuffer() .Length 结合使用的开销比使用.ToArray()少。

跳出来的第一件事是始终将using语句与任何实现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();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM