c++的结构体数据我已经用C#写过了需要转换的类也准备好了,之前写了好多次,但是就是无法获取数据。估计是中间代码写的有问题,还望高手麻烦写下using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Runtime.InteropServices; 
using System.Net; 
using System.Net.Sockets; namespace ConsoleClient 

    /// <summary> 
    /// C#版的 C++结构体 
    /// </summary> 
    public class StructHandler 
    { 
        enum ProtocolID 
        { 
            //登录 
            Login, 
            //退出 
            LogOut, 
            //指令 
            Command, 
            //数据 
            Data, 
        } 
        enum ProtocolAction 
        { 
            //操作成功 
            SUCCREQUEST, 
            //操作失败 
            FAILREQUEST, 
            //超时 
            TimeOut, 
            //开始发送数据 
            BEGIN, 
            //继续发送数据 
            CONTINUE, 
            //数据发送结束 
            END 
        }         [Serializable] 
        [StructLayout(LayoutKind.Sequential, Pack = 1)] 
        public struct ResponseLogin 
        { 
            //编号 
            long Id; 
            //帐号 
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] 
            char[] Username; 
            //口令 
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)] 
            char[] Password; 
        }         [Serializable] 
        [StructLayout(LayoutKind.Sequential, Pack = 1)] 
        public struct RequestLogin 
        { 
            //协议ID 
            ProtocolID CmdID; 
            ResponseLogin LoginData; 
        }         [Serializable] 
        [StructLayout(LayoutKind.Sequential, Pack = 1)] 
        public struct PacketHead 
        { 
            //厂商ID 
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 21)] 
            byte[] Maker; 
            //命令ID 
            byte CmdID; 
            //设备ID 
            int DeviceID; 
        }         [Serializable] 
        [StructLayout(LayoutKind.Sequential, Pack = 1)] 
        public struct MessageBody 
        { 
            //消息头 
            PacketHead Head; 
            //状态年月日时分秒 
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] 
            char[] stateDataTime; 
            //状态数据 
            byte StateData; 
            //状态类别 
            int StateTemp; 
        }         public struct ClientMessage 
        { 
            //协议ID 
            ProtocolID CmdID; 
            MessageBody Body; 
        } 
    }     class Server 
    { 
        static void Main(string[] args) 
        { 
            IPAddress m_ipaddress = IPAddress.Parse("127.0.0.1"); 
            int m_port = Convert.ToInt32(8088); 
            IPEndPoint m_ipep = new IPEndPoint(m_ipaddress, m_port); 
            Socket m_scoket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
            try 
            { 
                m_scoket.Connect(m_ipep); 
                //发送ID:1000 Username:admin  Passwprd:888888 
                // 
                // 如何发送结构体数据,接收结构体数据(还望高手帮忙) 
                // 
                // while (true){} 获取数据 
            } 
            catch 
            {             } 
        }         /// <summary> 
        /// (结构体)数据转换 
        /// </summary> 
        /// <returns> </returns> 
        private byte[] Struct2Bytes<T>(T obj)
        {
            int size = Marshal.SizeOf(obj);
            byte[] bytes = new byte[size];
            IntPtr arrPtr = Marshal.UnsafeAddrOfPinnedArrayElement(bytes, 0);
            Marshal.StructureToPtr(obj, arrPtr, true);
            return bytes;
        }
        private T Bytes2Struct<T>(byte[] bytes)
        {
            IntPtr arrPtr = Marshal.UnsafeAddrOfPinnedArrayElement(bytes, 0);
            return (T)Marshal.PtrToStructure(arrPtr, typeof(T));
        }
        public static byte[] Serialize(object obj)
        {
            BinaryFormatter binaryF = new BinaryFormatter();
            MemoryStream ms = new MemoryStream(1024 * 10);
            binaryF.Serialize(ms, obj);
            ms.Seek(0, SeekOrigin.Begin);            byte[] buffer = new byte[(int)ms.Length];
            ms.Read(buffer, 0, buffer.Length);
            ms.Close();            return buffer;
        }
        public static object Deserialize(byte[] buffer)
        {
            BinaryFormatter binaryF = new BinaryFormatter();
            MemoryStream ms = new MemoryStream(buffer, 0, buffer.Length, false);            object obj = binaryF.Deserialize(ms);
            ms.Close();            return obj;
        }
        public byte[] StructToBytes(object structObj)
        {
            //得到结构体的大小
            int size = Marshal.SizeOf(structObj);
            //分配结构体大小的内存空间
            IntPtr buffer = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.StructureToPtr(structObj, buffer, true);
                //创建byte数组
                byte[] bytes = new byte[size];
                //从内存空间拷到byte数组
                Marshal.Copy(buffer, bytes, 0, size);
                //返回byte数组
                return bytes;
            }
            finally
            {
                //释放内存空间
                Marshal.FreeHGlobal(buffer);
            }
        }
        public object BytesToStruct(byte[] bytes, Type strcutType)
        {
            //获取结构大小
            int size = Marshal.SizeOf(strcutType);
            //byte数组长度小于结构的大小
            if (size > bytes.Length)
            {
                //返回空
                return null;
            }
            IntPtr buffer = Marshal.AllocHGlobal(size);
            try
            {
                //将byte数组拷到分配好的内存空间
                Marshal.Copy(bytes, 0, buffer, size);
                //返回结构
                return Marshal.PtrToStructure(buffer, strcutType);
            }
            finally
            {
                //释放内存空间
                Marshal.FreeHGlobal(buffer);
            }
        }
    } 

我这里需要发送 ID=1000,USERNAME=ADMIN,PASSWORD=888888和一些结构体
然后获取结构体数据

解决方案 »

  1.   

    你不是都写好了吗?
    public byte[] StructToBytes(object structObj)     class Server 
        { 
            static void Main(string[] args) 
            { 
                IPAddress m_ipaddress = IPAddress.Parse("127.0.0.1"); 
                int m_port = Convert.ToInt32(8088); 
                IPEndPoint m_ipep = new IPEndPoint(m_ipaddress, m_port); 
                Socket m_scoket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
                try 
                { 
                    m_scoket.Connect(m_ipep); 
    m_scoket.Send(StructToBytes(object ));
                    //发送ID:1000 Username:admin  Passwprd:888888 
                    // 
                    // 如何发送结构体数据,接收结构体数据(还望高手帮忙) 
                    // 
                    // while (true){} 获取数据 
                } 
                catch 
                {             } 
            } 
      

  2.   

    简单的方法是序列化,收到序列化数据再还原,最好是soap, 简单对象传输协议,
      

  3.   

    m_scoket.Send(StructToBytes(object )); 
    m_scoket.re.......接收
    发送 ID=1000,USERNAME=ADMIN,PASSWORD=888888和一些结构体 
    然后获取结构体数据 的部分代码,我始终获取不了数据,代码写的很差还要高手帮忙写下中间一部分代码具体是怎么实现的,,谢谢了
      

  4.   

    http://cid-181e9b2001d6aa91.spaces.live.com/blog/cns!181E9B2001D6AA91!395.entry?_c=BlogPart
      

  5.   

    汗……我是搞web开发的,c/s中的Socket通信我不熟……
    现在楼主的问题主要就是怎么把这个结构体发出去,还有就是怎么接收是吗?
      

  6.   

    你得要知道你的server端是怎么发送数据的才能解析啊。帖server端的代码吧。
      

  7.   

    你新建2个控制台工程:            byte[] bytes = new Byte[1024];            IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
                IPAddress ipAddress = ipHostInfo.AddressList[0];
                IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 11000);            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);            try
                {
                    listener.Bind(localEndPoint);
                    listener.Listen(10);                while (true)
                    {
                        Console.WriteLine("Waiting for a connection...");                    Socket handler = listener.Accept();
                        data = null;
                        int bytesRec;                    while (true)
                        {
                            bytes = new byte[1024];
                            bytesRec = handler.Receive(bytes);
                            BinaryFormatter serializer = new BinaryFormatter();
                            MemoryStream ms = new MemoryStream(bytes);
                            StructHandler.ResponseLogin rl = (StructHandler.ResponseLogin)serializer.Deserialize(ms);
                            Console.WriteLine(rl.Id);
                            Console.WriteLine(rl.Username);
                            Console.WriteLine(rl.Password);
                        }                    // Show the data on the console.
                        Console.WriteLine("Text received : {0}", data.Substring(0, bytesRec - 5));                    // Echo the data back to the client.
                        byte[] msg = Encoding.ASCII.GetBytes(data);                    handler.Send(msg);
                        handler.Shutdown(SocketShutdown.Both);
                        handler.Close();
                    }            }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                }            Console.WriteLine("\nPress ENTER to continue...");
                Console.Read();             IPHostEntry ipe = Dns.GetHostEntry(Dns.GetHostName());
                IPAddress m_ipaddress = ipe.AddressList[0];
                IPEndPoint m_ipep = new IPEndPoint(m_ipaddress, 11000);
                Socket m_scoket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                try
                {
                    m_scoket.Connect(m_ipep);
                    StructHandler.ResponseLogin rl = new StructHandler.ResponseLogin();
                    rl.Id = 1000;
                    rl.Username = "admin".ToCharArray();
                    rl.Password = "888888".ToCharArray();
                    BinaryFormatter serializer = new BinaryFormatter();
                    System.IO.MemoryStream memStream = new System.IO.MemoryStream();
                    serializer.Serialize(memStream, rl);
                    int result = m_scoket.Send(memStream.ToArray());
                    Console.Read();
                    
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }先运行第一个,再运行第二个
      

  8.   

    汗……我是搞web开发的,c/s中的Socket通信我不熟…… 
    现在楼主的问题主要就是怎么把这个结构体发出去,还有就是怎么接收是吗?是的,,我需要的就是怎么发送结构体数据,获取结构体数据
    等下我发我写的发送的结构体数据
      

  9.   

            static string getMessage(string sender,int nSize)
            {
                int iSize = Encoding.Default.GetByteCount(sender);
                string sNew = sender;
                for (int i = iSize; i <= nSize - 1; i++)
                {
                    sNew += "\0";
                }
                return sNew;
            }
            static void Main(string[] args)
            {
                IPAddress m_ipaddress = IPAddress.Parse("127.0.0.1");
                int m_port = 8088;
                IPEndPoint m_ipep = new IPEndPoint(m_ipaddress, m_port);
                Socket m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
                try
                {
                    m_Socket.Connect(m_ipep);
                    UserInfo us=new UserInfo();
                    us.Id = ProtocolID.Login;
                    us.Id=10000;
                    us.Username=getMessage("admin",20);
                    us.Password=getMessage("888888",50);                MemoryStream m_Stream=new MemoryStream();
                    us.MessageSize += sizeof(ProtocolID);                us.MessageSize += sizeof(int);                us.MessageSize += Encoding.Default.GetByteCount(us.UserName);                us.MessageSize += Encoding.Default.GetByteCount(us.UserPws);
                    //压入字节流的尺寸
                    byte[] m_tmp = BitConverter.GetBytes(us.MessageSize);
                    m_Stream.Write(m_tmp, 0, sizeof(int));
                    //压入命令字字节
                    m_tmp = BitConverter.GetBytes(Convert.ToInt32(us.CommandID));
                    m_Stream.Write(m_tmp, 0, sizeof(int));
                    //压入企业代码字节
                    m_tmp = BitConverter.GetBytes(us.CompanyID);
                    m_Stream.Write(m_tmp, 0, sizeof(int));
                    //压入用户名称字节
                    m_tmp=Encoding.Default.GetBytes(us.UserName);
                    m_Stream.Write(m_tmp, 0, Encoding.Default.GetByteCount(us.UserName));
                    //压入用户口令字节
                    m_tmp=Encoding.Default.GetBytes(us.UserPws);
                    m_Stream.Write(m_tmp, 0, Encoding.Default.GetByteCount(us.UserPws));               //m_tmp=m_Stream.ToArray();                m_Socket.Send(m_tmp);
                    byte[] m_buffer=new byte[8192];
                    m_Socket.Receive(m_buffer);
                }
                catch (Exception e)
                {            }
            }
      

  10.   

    我是参考:http://www.cnblogs.com/showna/articles/760385.html
    http://hi.baidu.com/yangliangwang/blog/item/1a0116138ff098d6f6039ea9.html
    但是理解能力太差。反应慢,,理解不过来
      

  11.   

    别着急,慢慢来,不过这方面我也不太熟,Socket和C++,正好都是我不擅长的,我尽量帮吧
    现在你用C#发送结构体成功了吧,是不是就剩在C++接收的时候获取不了了?
      

  12.   

    发送数据就是1楼红色的接收..第1 你必须知道当前数据是多大 看你的代码 包的大小基本是固定的..根据大小转换数据为结构提就可以了.需要发送 ID=1000,USERNAME=ADMIN,PASSWORD=888888和一些结构体   ResponseLogin _Login = new ResponseLogin();
                _Login.Id=1000;            _Login.Password = new char[50];
                _Login.Username = new char[20];            "ADMIN".ToCharArray().CopyTo(_Login.Username, 0);
                "88888".ToCharArray().CopyTo(_Login.Password, 0);            byte[] _ValueBytes = Struct2Bytes<ResponseLogin>(_Login); //大小应该是78个字节 
      
    发送 _ValueBytes就可以了..   但如果你另外一个是C++ 根据你翻译过来的结构体不对...感觉而已.
      

  13.   

        /// <summary> 
        /// C#版的 C++结构体 
        /// </summary> 
    顶一下
      

  14.   

    发送是成功了,但是获取的数据流不正确,C++中断获取的数字和我发送的不一致,我搞不清楚状况。。但是目前比较好的解决方法就是先把 结构体数据——》 转换成 Byte 【】 发送,然后Byte 【】 再转换成结构体,输出
    但是这个怎么传送数据参数和结构体,具体的搞不清楚。
    这个关键就是C# SOCKET的写法 和 C++结构体,格式化处理,或者数据流操作。
      

  15.   

    登陆结构体:enum ProtocolID
    {
    //系统登录
    Login,
    //系统登出
    LogOut,
    //指令
    Command,
    //设备数据
    Data,
    };
    enum ProtocolOperation
    { //请求服务器插入新数据
    Insert,
    //请求服务器改写旧数据
    Update,
    //请求服务器删除指定的数据
    Delete,
    //请求服务器查询数据
    Select
    };
    enum ProtocolAction
    {
    //请求操作操作成功
    SUCCREQUEST,
    //请求操作操作失败
    FAILREQUEST,
    //超时
    TimeOut,
    //开始发送数据
    BEGIN,
    //继续发送数据
    CONTINUE,
    //数据发送结束
    END
    };typedef struct 
    {
    //企业帐号
    long CompanyID;
    //个人帐号
    char Account[20];
    //口令
    char Password[50];
    }ResponseLogin;typedef struct{
        ProtocolID CmdID;
        ResponseLogin LoginData;
    }RequestLogin;//系统错误
    typedef struct
    {
    //行为代码
    ProtocolAction Code;
    //返回消息
    char Message[200];
    }AnswerInfo;//系统消息
    typedef struct
    {
        AnswerInfo MessageInfo;
    }RequestAnswerInfo;//登陆结束结构体(54)
    typedef struct
    {
        //操作类型
        ProtocolOperation OperationID;
        //回复类别
        RequestAnswerInfo AnserInfo;
        //数据
        TStaff Staff;
    }RequestStaffBody;
    typedef struct
    {
        //协议ID
        ProtocolID pID;
        //数据
        RequestStaffBody Body;
    }RequestStaff;
    GPS信息结构体ClientMessage(5)
    //设备包头
    typedef struct{
    //厂商ID
    byte Maker[21];
    //命令命令ID
    byte CmdID;
    //设备ID
    int DeviceID;
    //设备服务端口
    int ServerPort;
    }PacketHead;
    //0x41-42-43-44系列发给客户端的消息
    typedef struct{
    // 消息头
    PacketHead Head;
    // 状态时间
    char YearMonth[20];
    // 状态类型
    int Direction;
    // 状态数据
    byte StateData;
    }MessageBody;//反馈到客户端的消息
    typedef struct{
    //协议ID
    ProtocolID ProtocolCmdID;
    MessageBody Body;
    }ClientMessage;c++的结构代码,应该没有写错
      

  16.   

    帮你转一个把 ..
    long 转换为 int
    char[] 转换为 byte[] [Serializable]
            [StructLayout(LayoutKind.Sequential, Pack = 1)]
            public struct ResponseLogin
            {
                //编号 
                public int Id;
                //帐号 
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
                public byte[] Username;
                //口令 
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
                public byte[] Password;
            }这样看看...long 在C++里好象是32位的   char 好象是8位的