读取分割 TCP 数据包

发布于 2024-10-21 09:16:48 字数 2026 浏览 6 评论 0原文

我已经编写了大部分代码来处理服务器的传入数据包。数据包的格式始终为 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();
}

I have written most of the code to handle incoming packets for my server. The format for packets is always int/int/int/string/string, and the first int is the size of the packet. I need to figure out some way to check and see if the entire packet arrived or if I need to wait for more pieces to come in, however with the way I have written my code, I can't think of a good way. Any help would be great as my brain is probably overthinking this.

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();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

活泼老夫 2024-10-28 09:16:48

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

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

What you have should work, as the underlying stream will wait for more data. That is, if you were to call clientStream.ReadByte and there aren't any bytes available, the method will block until data comes in or until the stream is closed--in this case, probably disconnected by the server.

BinaryReader will until there's enough data to satisfy the read request, so the code should work as expected.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文