先给大家看段代码:
这是我定义的一个结构体,
    [StructLayout(LayoutKind.Sequential, Size = 12, CharSet = CharSet.Ansi)]
    public struct SessionKeyMessage
    {
        [MarshalAs(UnmanagedType.U2)]
        public ushort message_len;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]
        public string message_id;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
        public string session_key;
    }
下面为将字节流转换为结构体的方法:
        public static object BytesToStruct(byte[] bytes, Type strcutType)
        {
            int size = Marshal.SizeOf(strcutType);
            IntPtr buffer = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.Copy(bytes, 0, buffer, size);
                return Marshal.PtrToStructure(buffer, strcutType);
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }
        }在BUTTON事件中,做了如下处理:
        private void ReceiveSessionKey()
        {            
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.Connect(host, port);
            if (!socket.Connected)
                MessageBox.Show("not connected");
        
            byte[] recvBytes = new byte[1024];
            int bytes = 0;
            bytes = socket.Receive(recvBytes, recvBytes.Length, SocketFlags.None);             skm = new SessionKeyMessage();
            skm = (SessionKeyMessage)NetStreamUtil.BytesToStruct(recvBytes, skm.GetType());
            using (StreamWriter sw = new StreamWriter("11.txt", false, Encoding.Default))
            {
                sw.WriteLine(skm.message_len);
                sw.WriteLine(skm.message_id);
                sw.WriteLine(skm.session_key + ' ' + skm.session_key.Length);
            }      
        }
结果发现message_id和session_key两个成员的值比实际的值都少了一个字符,被右截位了。
请教一下,上面的代码有何问题,调试了一天了,怎么也查不出来。我把网络字节流通过Encoding.ASCII.GetString()
方法转换后取得的字符串部分看确实比上面的办法取出来的要多一个字符
请各位大大帮帮忙,万发火急

解决方案 »

  1.   

     int size = Marshal.SizeOf(strcutType); 
    ==>
     int size = Marshal.SizeOf(strcutType)+ 1; 试试?
      

  2.   

    回楼上,还是同样的问题,不光是最后一个string被右截了一个字符,中间的string也被右截了一个字符
      

  3.   

    //得到结构体的大小
    int size = Marshal.SizeOf(structObj);
    byte[] bytes = new byte[size];
     //分配结构体大小的内存空间
    IntPtr structPtr = Marshal.AllocHGlobal(size);
    //将结构体拷到分配好的内存空间
    Marshal.StructureToPtr(structObj, structPtr, false);
    //从内存空间拷到byte数组
    Marshal.Copy(structPtr, bytes, 0, size);
      

  4.   

    这个可能是因为ANSI的string是以\0为结束符的原因
      [StructLayout(LayoutKind.Sequential,Packet=1, Size = 14, CharSet = CharSet.Ansi)] 
        public struct SessionKeyMessage 
        { 
            [MarshalAs(UnmanagedType.U2)] 
            public ushort message_len; 
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 3)] 
            public string message_id; 
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)] 
            public string session_key; 
        }这样再试试 
      

  5.   

    不如全部用byte类型的 省事
      

  6.   

    4楼的办法对接收数据可以解决,但发送数据的时候,由于服务器对每个包裹消息的大小都做了限制,把string类型的长度加1就有麻烦了
      

  7.   

    都一样吧,那你怎么发送的,数据结构很复杂吗?
    你可以像上面那样用byte[]对结构体赋值啊