c# - 读取拆分的 TCP 数据包

标签 c# .net tcp packet custom-protocol

我已经编写了大部分代码来为我的服务器处理传入的数据包。数据包的格式始终是 int/int/int/string/string,第一个 int 是数据包的大小。我需要想出一些方法来检查并查看是否整个数据包都到达了,或者我是否需要等待更多的数据包进来,但是按照我编写代码的方式,我想不出一个好的方法。任何帮助都会很棒,因为我的大脑可能对此考虑过多。

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.ServerDataSent = (RCONPacket.SERVERDATA_sent)reader.ReadInt32();

                Console.WriteLine("Packet Size: {0} RequestID: {1} ServerData: {2}", packetsize, packet.RequestId, packet.ServerDataSent);

                // 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.ServerDataSent)
            {
                case RCONPacket.SERVERDATA_sent.SERVERDATA_AUTH:
                {
                    ReplyAuthRequest(packet.RequestId, clientStream);
                    break;
                }
                case RCONPacket.SERVERDATA_sent.SERVERDATA_EXECCOMMAND:
                {
                    ReplyExecCommand();
                    break;
                }
                default:
                {
                    break;
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            break;
        }
    }

    tcpClient.Close();
}

最佳答案

您所拥有的应该可以工作,因为底层流将等待更多数据。也就是说,如果您要调用 clientStream.ReadByte 并且没有任何可用字节,则该方法将阻塞直到数据进入或直到流被关闭——在这种情况下,可能断开连接服务器。

BinaryReader 将一直执行直到有足够的数据满足读取请求,因此代码应该按预期工作。

关于c# - 读取拆分的 TCP 数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5289651/

相关文章:

c# - 从物理路径获取相对虚拟路径

C# - 递归分组

c - TCP多客户端服务器程序

客户端关闭套接字后,C# tcp 异步监听器卡在我的 on_receive 回调中

.net - 日志框架与 System.Diagnostics 跟踪

ruby - 在 ruby​​ 中发送和接收 TCP 数据

c# - 如何在 Excel 中使用正确的列打开 CSV 文件

C# 反向 UrlPathEncode

c# - 以异步方式以编程方式将 UIElement 添加到 View

c# - 我可以从 WindowsPrincipal 获取 Active Directory 属性吗?