首页 > 解决方案 > 如何处理客户端/服务器应用程序代码中的网络数据包?

问题描述

我正在使用 C# 创建一个客户端/服务器应用程序,我想知道在 C# 代码中处理数据包的最佳方法。

根据我的阅读,我可以 A)使用 Marshal 类从数据包原始缓冲区构造一个安全类,或者 B)在不安全的上下文中使用原始指针将数据包缓冲区直接转换为结构并在我的代码中使用它。

我可以在这两种方法中看到很大的问题。例如,使用 Marshal 似乎非常麻烦且难以维护(与指针解决方案相比),另一方面,在 C# 中指针的使用非常有限(例如,我什至不能声明非原始类型的固定大小数组这是此类应用程序中的交易破坏者)。

也就是说,我想知道这两种方法中哪一种更适合处理网络数据包,以及是否有其他更好的方法。我对任何其他可能的解决方案持开放态度。

PS.:我实际上是在为已经存在的客户端/服务器应用程序创建一个自定义客户端,因此客户端和服务器之间的通信协议已经创建并且无法修改。所以我的 C# 客户端需要遵守这个已经存在的协议到它的较低级别的细节(例如,数据包中每个信息的二进制偏移量是固定的,需要得到尊重)。

标签: c#client-servermarshalling

解决方案


处理网络数据包的最佳方法。您必须创建附加到实际数据包标头的有效负载,并且接收客户端始终首先读取标头并将其转换为实际长度。然后设置您在标头中收到的缓冲区长度。它将完美地工作而不会丢失任何数据包。它还将改善内存泄漏问题。您无需创建硬编码数组即可获取缓冲区字节。只需将实际字节长度附加到数据包的标头即可。它将动态设置缓冲区字节。

喜欢。

  public void SendPackettoNetwork(AgentTransportBO ObjCommscollection, Socket Socket)
    {
        try
        {
            byte[] ActualBufferMessage = PeersSerialization(ObjCommscollection);
            byte[] ActualBufferMessagepayload = BitConverter.GetBytes(ActualBufferMessage.Length);
            byte[] actualbuffer = new byte[ActualBufferMessage.Length + 4];
            Buffer.BlockCopy(ActualBufferMessagepayload, 0, actualbuffer, 0, ActualBufferMessagepayload.Length);
            Buffer.BlockCopy(ActualBufferMessage, 0, actualbuffer, ActualBufferMessagepayload.Length, ActualBufferMessage.Length);
            Logger.WriteLog("Byte to Send :" + actualbuffer.Length, LogLevel.GENERALLOG);
            Socket.Send(actualbuffer);
        }
        catch (Exception ex)
        {
            Logger.WriteException(ex);
        }
    }

只需传递您的传输类对象。在这里使用你的序列化方法我使用了类对象的二进制格式化程序序列化


推荐阅读