C# 如何在客户机/服务器应用程序代码中处理网络数据包?

C# 如何在客户机/服务器应用程序代码中处理网络数据包?,c#,client-server,marshalling,C#,Client Server,Marshalling,我正在使用C#创建一个客户机/服务器应用程序,我想知道用C#代码处理数据包的最佳方法 从我读到的内容来看,我可以A)使用封送处理类从数据包原始缓冲区构造一个安全类,或者B)在不安全上下文中使用原始指针直接将数据包缓冲区转换为结构,并在代码中使用它 我可以看出这两种方法都存在很大的问题。例如,与指针解决方案相比,使用Marshal似乎非常麻烦且难以维护,而另一方面,C#中指针的使用非常有限(例如,我甚至不能声明非原语类型的固定大小数组,这在此类应用程序中是一个交易破坏者) 也就是说,我想知道这两种

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

从我读到的内容来看,我可以A)使用封送处理类从数据包原始缓冲区构造一个安全类,或者B)在不安全上下文中使用原始指针直接将数据包缓冲区转换为结构,并在代码中使用它

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

也就是说,我想知道这两种方法中哪一种更适合处理网络数据包,以及是否有其他更好的方法。我愿意接受任何其他可能的解决办法


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

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

喜欢


只需传递传输类对象。这里我使用了类对象的二进制格式化程序序列化,这是处理网络数据包的最佳方法。您必须创建附加到实际数据包报头的有效负载,并且您的接收客户端总是首先读取报头并将其转换为实际长度。然后设置在标头中接收的缓冲区长度。它将完美地工作,不会丢失任何数据包。它还将改善内存泄漏问题。您不需要创建硬编码数组来获取缓冲区字节。只需将实际字节长度附加到数据包的头部。它将动态设置缓冲区字节

喜欢


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

坦率地说,您不应该通过封送器对套接字数据进行解码。您应该编写一个协议处理程序,相当手动地查看字节流,获取协议所需的内容。协议很少与编组要求匹配,甚至在讨论结束、编码等之前。顺便说一句,c完全支持非原语的固定大小缓冲区-它们被称为“固定缓冲区”。我有一个由4部分组成的博客系列,讨论可能有用的现代方法,开始:您正在处理网络7层中的两层。1) 传输层,您在其中通过流(TCP或UDP)串行发送数据。这就是Marc link所描述的。2) 应用程序层,其中有一个要发送/接收的类对象。因此,您实际上是在询问将类转换为字节以及将字节转换为类的应用程序层。c#是一个托管库,它不允许在字节与类之间进行转换。Microsoft设计c#托管库是为了消除Win XP(Win 95、Win 98、Win 2000、Win ME、WinNt)之前windows中经常出现的蓝屏崩溃。当指针未正确配置时,通常会出现蓝屏错误。因此,当NET3.5(与WinXP相同)几乎不可能使用指针时,在托管库中添加了大量检查以防止蓝屏异常。封送处理库具有防止蓝屏的检查功能,而不安全模式没有检查功能。c#不是将对象强制转换为字节(需要发送/接收)的最有效语言。您可以对强制转换使用二进制序列化。如果你需要更高效的代码,那么使用C++。坦率地说,你不应该通过封送器来解码套接字数据。您应该编写一个协议处理程序,相当手动地查看字节流,获取协议所需的内容。协议很少与编组要求匹配,甚至在讨论结束、编码等之前。顺便说一句,c完全支持非原语的固定大小缓冲区-它们被称为“固定缓冲区”。我有一个由4部分组成的博客系列,讨论可能有用的现代方法,开始:您正在处理网络7层中的两层。1) 传输层,您在其中通过流(TCP或UDP)串行发送数据。这就是Marc link所描述的。2) 应用程序层,其中有一个要发送/接收的类对象。因此,您实际上是在询问将类转换为字节以及将字节转换为类的应用程序层。c#是一个托管库,它不允许在字节与类之间进行转换。Microsoft设计c#托管库是为了消除Win XP(Win 95、Win 98、Win 2000、Win ME、WinNt)之前windows中经常出现的蓝屏崩溃。当指针未正确配置时,通常会出现蓝屏错误。因此,当NET3.5(与WinXP相同)几乎不可能使用指针时,在托管库中添加了大量检查以防止蓝屏异常。封送处理库具有防止蓝屏的检查功能,而不安全模式没有检查功能。c#不是将对象强制转换为字节(需要发送/重新发送)的最有效语言
  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);
        }
    }