使用UDP向局域网内计算机发送广播消息,并传递以下这个结构体:
public struct Astruct
    {
        public int seq;  
        public char[] name;
        public ulong len;
        public char[] data;
    } 
Astruct ast=new Astruct();
怎样用代码实现呢?
序列化的方法试了不行,UDP似乎不能接收网络传递过来的流,NetworkStream不适用于无连接的协议。
通过指针转换的办法,在C++里可以使用char* buffer=(char*)ast,但在C#里不行,不知道怎样把结构体转化为byte[]进行传递。
或者有没有别的办法实现在局域网中广播结构体~

解决方案 »

  1.   

    如果在C#中用指针的话,可以加上unsafe关键字试一试
      

  2.   

    System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(typeof(Astruct));
    xs.Serialize(stream, ast);
      

  3.   

    使用.net remoting进行广播信息,
      

  4.   

    序列化为bytes,然后网络发送。发送完后给个结束标记,再由接收端反序列化为结构体。
      

  5.   

    要是其它的机子也是.NET而且是同一个程序的话,可以用序列化的方式
    如果不是同一个程序,甚至都不是.NET的话自已用BinaryWriter BinaryReader来搞吧
    Astruct加一个方法,或只读属性 public byte[] GetRawData()或RawData
    里面用BinaryWriter把结构内的值按一定顺序写进去
    结构用一个构造函数public Astruct(byte[] data);里面用BinaryReader读取,怎么读取处你写入的顺序有关简单类型int,ulong与byte的转换可以BitConverter类来操作,更方便,至于char[]类型可以随便选个Encoding来搞定,还原的时候用同样的Encoding就行了。或者直接把一个char转成两个字节写进去。
      

  6.   

    如果char[] name和char[] data的长度是固定的,那么可以直接列集(Marshal)到byte数组。
    如果不是,可以用2楼的XmlSerializer(长度较长)或BinaryFormatter(比较精简)系列化成byte数组。传输以后再转回来。using System.Runtime.Serialization.Formatters.Binary;
    //...
        [Serializable]
        public struct Astruct
        {
            public int seq;
            public char[] name;
            public ulong len;
            public char[] data;        public byte[] GetSerializedBytes()
            {
                BinaryFormatter bf = new BinaryFormatter();                               //<---
                using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
                {
                    bf.Serialize(ms, this);                                               //<---系列化成byte数组
                    ms.Seek(0, System.IO.SeekOrigin.Begin);
                    return ms.ToArray();
                }
            }
            public static Astruct FromSerilizedBytes(byte[] data)
            {
                BinaryFormatter bf = new BinaryFormatter();
                using (System.IO.MemoryStream ms = new System.IO.MemoryStream(data))
                {
                    return (Astruct)bf.Deserialize( ms );                                 //<---从byte数组再转回来
                }
            }
        } 
      

  7.   

    补充一下,贴上我的程序:发送端:Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    IPEndPoint iep1 = new IPEndPoint(IPAddress.Broadcast, 9050);
    BinaryFormatter bf;
    bf = new BinaryFormatter();
    MemoryStream stream = new MemoryStream();
    Astruct ast = new Astruct();
    ast.seq = 4;
    ast.name = new char[] { 'n', 'a', 'm', 'e' };
    ast.len = 4;
    ast.data = new char[] { 'd', 'a', 't', 'a' };
    bf.Serialize(stream, ast);
    byte[] buff = stream.ToArray(); 
    sock.SendTo(buff, iep1);
    接收端:Socket sock = new Socket(AddressFamily.InterNetwork,
     SocketType.Dgram, ProtocolType.Udp);
                IPEndPoint iep = new IPEndPoint(IPAddress.Any, 9050);
                sock.Bind(iep);
                EndPoint ep = (EndPoint)iep;
    NetworkStream stream = new NetworkStream(sock);//取得服务端发送的数据(无论用哪种类型都无法接收到网络的流)
    BinaryFormatter bf;
    bf = new BinaryFormatter();
    Astruct reci = (Astruct)bf.Deserialize(stream);//反序列化数据
    Console.Write("name   is   :");
    Console.WriteLine(reci.name);
    Console.WriteLine("seq   is   :" + reci.seq);
    Console.WriteLine("len   is   :" + reci.len);
    Console.Write("data   is   :");
    目前的主要问题出在如何能够发送和接收到。接收端现在能编译通过,但只要运行就会有异常。不知道该怎样做才能有效获取到网络中的数据流。解析是后面的事了。刚看到7楼给了个例程,我一会儿试一下。
      

  8.   


    看样子你的问题主要不在序列化上面
    UDP只能用Send / Receive,
    NetworkStream是用在TCP上的另外建议你用TCPClient/UDPClient,这两个都是在Socket上的封装
      

  9.   

    9L:
    我也觉得我的主要问题不是序列化,我是想知道怎么接收,如果不用NetworkStream该用什么呢?
    TCPClient/UDPClient的功能用socket不是也可以实现吗?我就是这样用的。为什么建议我用那两个呢?
    UDP怎样用Send和Receive接收结构体序列化后产生的流呢?应该不能像普通的字节流那样发送和接收吧?
    发送端:
    string hostname = Dns.GetHostName();
    byte[] data = Encoding.ASCII.GetBytes(hostname);
    IPEndPoint iep1 = new IPEndPoint(IPAddress.Broadcast, 9050);
    sock.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.Broadcast, 1);
    sock.SendTo(data, iep1);
    接收端:
    Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    IPEndPoint iep = new IPEndPoint(IPAddress.Any, 9050);
    sock.Bind(iep);
    EndPoint ep = (EndPoint)iep;
    byte[] data = new byte[1024];
    int recv = sock.ReceiveFrom(data, ref ep);
    string stringData = Encoding.ASCII.GetString(data, 0, recv);
    Console.WriteLine("received: {0} from: {1}",stringData, ep.ToString());在这段上面怎么改造呢?把结构体序列化过后。
      

  10.   

    已解决。
    说明一下我的修改方法:
    修改的内容有: 
    1.从发送端到接收端的byte[]接收长度改变了,因此应该获取传过来的参数的长度,并修改为合适。 
    2.出现过一个cast的问题,好像是说结构序列化以后还是对象,不能转换为值类型,所以修改成类。 
    3.虽然在send和receive端定义了两个一摸一样的结构,但是系统还是认为是不同的,所以将公共类型定义独立出来建了一个工程。 
    4.send和receive的各自的解决方案均要添加已存在的工程comm,然后添加引用到那个工程里。
    谢谢上面的各位~~!
    散分啦~