2015-06-22 85 views
0

我想通过将它转换成字节数组来组播数据结构数据。一切工作正常与下面的代码,除了字符串变量的结构数据没有收到客户端从服务器发送,而是显示空字符串或其他字符。请建议我解决这个问题。在C#中使用udpmulticasting发送数据结构数据

谢谢inadvance。

这里是我的代码:

ServerCode

struct CIFSPacket 
     { 
      public int quantity; 
      public double price; 
      public string Buffer; 
     } 
     static void Main(string[] args) 
     { 
      Socket server=null; 
      try 
      { 
       server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 
       IPEndPoint iep = new IPEndPoint(IPAddress.Parse("224.100.0.1"), 9050); 

       int i = 0; 
       while (true) 
       { 
        byte[] structData = new byte[4096]; 
        //server.sendto 
        CIFSPacket pkt = new CIFSPacket(); 
        pkt.quantity = i++; 
        pkt.price = i + 0.12; 
        pkt.Buffer = "RELIANCE";      
        structData = StructureToByteArray(pkt); 
        server.SendTo(structData, iep);           
        Console.WriteLine(pkt.Buffer+" - "+pkt.quantity+" - "+pkt.price);      
       } 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.ToString()); 
      } 
      finally 
      { 
       if (server != null) 
        server.Close(); 
      } 
     } 
private static byte[] StructureToByteArray(CIFSPacket str) 
     { 
      int size = Marshal.SizeOf(str); 
      byte[] arr = new byte[size]; 
      IntPtr ptr = Marshal.AllocHGlobal(size); 

      Marshal.StructureToPtr(str, ptr, true); 
      Marshal.Copy(ptr, arr, 0, size); 
      Marshal.FreeHGlobal(ptr); 

      return arr; 
     } 

ClientCode

public struct CIFSPacket 
     { 
      public int quantity; 
      public double price; 
      public string Buffer; 
     } 

static void Main(string[] args) 
     { 
      Socket sock = null; 
      CIFSPacket pkt; 
      try 
      { 
       sock = new Socket(AddressFamily.InterNetwork, 
       SocketType.Dgram, ProtocolType.Udp); 
       Console.WriteLine("Ready to receive…"); 
       IPEndPoint iep = new IPEndPoint(IPAddress.Any, 9050); 
       EndPoint ep = (EndPoint)iep; 
       sock.Bind(iep); 
       sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, 
        new MulticastOption(IPAddress.Parse("224.100.0.1"))); 

       while (true) 
       { 
        byte[] data = new byte[4096];      
        int recv = sock.ReceiveFrom(data, ref ep);      
        pkt = ByteArrayToStructure(data); 
        Console.WriteLine(pkt.Buffer + " -- " + pkt.quantity + " -- " + pkt.price); 
       } 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.ToString()); 
      } 
      finally 
      { 
       sock.Close(); 
       Console.ReadLine(); 
      }    
     } 

private static CIFSPacket ByteArrayToStructure(byte[] arr) 
     { 
      CIFSPacket str = new CIFSPacket(); 
      int size = Marshal.SizeOf(str); 
      IntPtr ptr = Marshal.AllocHGlobal(size); 
      Marshal.Copy(arr, 0, ptr, size); 

      str = (CIFSPacket)Marshal.PtrToStructure(ptr, str.GetType()); 
      Marshal.FreeHGlobal(ptr); 

      return str; 
     } 

输出

Server

Client

回答

0

的问题是,string型在你的结构是一个管理的指针,而不是一个值类型。

尝试

[MarshalAsAttribute(UnmanagedType.LPArray, ArraySubType=UnmanagedType.U2, SizeConst=Max_Size_Of_Your_String)] 
public char[] Buffer=new char[Max_Size_Of_Your_String]; 

或者更换

public string Buffer; 

,你应该能够使用

[MarshalAsAttribute(UnmanagedType.XXX)] 

在你public string Buffer声明,告诉编译器如何将字符串转换到/从字节。 XXX是支持的字符串类型之一,例如LPStr。但在这种情况下,您需要在相应的属性中指定字符串和/或结构的最大大小,以便编译器知道为字符串分配多少空间。

您可能需要查看下面的文章以了解更多信息:

https://limbioliong.wordpress.com/2011/08/28/passing-managed-structures-with-strings-to-unmanaged-code-part-3/

convert struct handle from managed into unmanaged C++/CLI