socket编程中结构体与字节流转换出现的问题

batistawjp 2010-03-09 08:08:21
先给大家看段代码:
这是我定义的一个结构体,
[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()
方法转换后取得的字符串部分看确实比上面的办法取出来的要多一个字符
请各位大大帮帮忙,万发火急
...全文
254 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
xingyuebuyu 2010-03-09
  • 打赏
  • 举报
回复
都一样吧,那你怎么发送的,数据结构很复杂吗?
你可以像上面那样用byte[]对结构体赋值啊
batistawjp 2010-03-09
  • 打赏
  • 举报
回复
4楼的办法对接收数据可以解决,但发送数据的时候,由于服务器对每个包裹消息的大小都做了限制,把string类型的长度加1就有麻烦了。。。
rizher 2010-03-09
  • 打赏
  • 举报
回复
不如全部用byte类型的 省事
xingyuebuyu 2010-03-09
  • 打赏
  • 举报
回复
这个可能是因为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;
}

这样再试试
wuyq11 2010-03-09
  • 打赏
  • 举报
回复
//得到结构体的大小
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);
batistawjp 2010-03-09
  • 打赏
  • 举报
回复
回楼上,还是同样的问题,不光是最后一个string被右截了一个字符,中间的string也被右截了一个字符
鸭梨山大帝 2010-03-09
  • 打赏
  • 举报
回复
int size = Marshal.SizeOf(strcutType);
==>
int size = Marshal.SizeOf(strcutType)+ 1;

试试?

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧