软件原来是用DELPHI写的,翻译成C#,服务器端是VC写的,原来的协议比较复杂,我就用DELPHI写了一个非常简单的,用的INDY组件
C#发送结构体,但是有几个问题,发送字符串与BYTE类型的都没有问题,但是发送整数据却不对,另外发送结构体数据应该如何写呢?
上代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using MTWS.Net.SocketClient;namespace MTWS.Net.AppCode
{
public partial class TestTcp : Form
{
public TestTcp()
{
InitializeComponent();
} struct TMsgHeadInfo
{
//[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char MsgCode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char[] MsgType;
public byte Sender;
//public int SendInt;
} struct TMsgBody
{
public TMsgHeadInfo msghead;
public Int32 body; //这里哪个类型对就DELPHI里的integer?
} public static byte[] StructToBytes(object structObj)
{
//得到结构体的大小
int size = Marshal.SizeOf(structObj);
//创建byte数组
byte[] bytes = new byte[size];
//分配结构体大小的内存空间
IntPtr structPtr = Marshal.AllocHGlobal(size);
//将结构体拷到分配好的内存空间
Marshal.StructureToPtr(structObj, structPtr, false);
//从内存空间拷到byte数组
Marshal.Copy(structPtr, bytes, 0, size);
//释放内存空间
Marshal.FreeHGlobal(structPtr);
//返回byte数组
return bytes;
} private void TestTcp_Load(object sender, EventArgs e)
{
} private void button1_Click(object sender, EventArgs e)
{
int ret;
TMsgBody msgbody;
//TMsgHeadInfo msghead;
TCPClient tcp = new TCPClient();
string code = "zp";
string type = "ai";
//string body = "cc";
ret = tcp.ConnectServer("127.0.0.1", 3578);
if (ret == 0)
{
MessageBox.Show("连接服务器失败");
}
else
{
MessageBox.Show("连接服务器成功"); msgbody.msghead.MsgCode = code.ToCharArray();
msgbody.msghead.MsgType = type.ToCharArray();
msgbody.msghead.Sender = 5;
msgbody.body = 44;// body.ToCharArray();
byte[] msg = StructToBytes(msgbody);
if (tcp.SendMsg(msg) > 0)
{
MessageBox.Show("发送成功");
}
else
{
MessageBox.Show("发送失败");
}
} }
}
}
C#发送结构体,但是有几个问题,发送字符串与BYTE类型的都没有问题,但是发送整数据却不对,另外发送结构体数据应该如何写呢?
上代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using MTWS.Net.SocketClient;namespace MTWS.Net.AppCode
{
public partial class TestTcp : Form
{
public TestTcp()
{
InitializeComponent();
} struct TMsgHeadInfo
{
//[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char MsgCode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char[] MsgType;
public byte Sender;
//public int SendInt;
} struct TMsgBody
{
public TMsgHeadInfo msghead;
public Int32 body; //这里哪个类型对就DELPHI里的integer?
} public static byte[] StructToBytes(object structObj)
{
//得到结构体的大小
int size = Marshal.SizeOf(structObj);
//创建byte数组
byte[] bytes = new byte[size];
//分配结构体大小的内存空间
IntPtr structPtr = Marshal.AllocHGlobal(size);
//将结构体拷到分配好的内存空间
Marshal.StructureToPtr(structObj, structPtr, false);
//从内存空间拷到byte数组
Marshal.Copy(structPtr, bytes, 0, size);
//释放内存空间
Marshal.FreeHGlobal(structPtr);
//返回byte数组
return bytes;
} private void TestTcp_Load(object sender, EventArgs e)
{
} private void button1_Click(object sender, EventArgs e)
{
int ret;
TMsgBody msgbody;
//TMsgHeadInfo msghead;
TCPClient tcp = new TCPClient();
string code = "zp";
string type = "ai";
//string body = "cc";
ret = tcp.ConnectServer("127.0.0.1", 3578);
if (ret == 0)
{
MessageBox.Show("连接服务器失败");
}
else
{
MessageBox.Show("连接服务器成功"); msgbody.msghead.MsgCode = code.ToCharArray();
msgbody.msghead.MsgType = type.ToCharArray();
msgbody.msghead.Sender = 5;
msgbody.body = 44;// body.ToCharArray();
byte[] msg = StructToBytes(msgbody);
if (tcp.SendMsg(msg) > 0)
{
MessageBox.Show("发送成功");
}
else
{
MessageBox.Show("发送失败");
}
} }
}
}
解决方案 »
- 请教 lambda
- tabControl1一个问题请赐教
- C# WinFrom 自定义安装包
- vs2010中的web应用程序和web站点有什么区别?
- 怎么控制他的输出字符串的长度<asp:lable id="lable1" runat="server" text='<%# Eval("mm1")%>'></lable>
- .NET网页编程问题(在线等)
- 今天遇到一个非常奇怪的问题,窗口透明度和窗口嵌入桌面竟然会冲突
- c#中如何禁止在RichTextBox中输入图片呢?
- 问一个C#的枚举问题...
- 怎么样用C#创建一个文件的快捷方式????
- C# 如何获取word、浏览器、pdf等的选中文本?
- 两个窗体都包含一样的groupbox和groupbox中的控件,如何方便的传值
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using MTWS.Net.SocketClient;
namespace MTWS.Net.AppCode
{
public partial class TestTcp : Form
{
public TestTcp()
{
InitializeComponent();
}
struct TMsgHeadInfo
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char[] MsgCode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char[] MsgType;
public byte Sender;
}
struct TMsgBody
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public TMsgHeadInfo[] msghead;
public Int32 body; //这里哪个类型对就DELPHI里的integer?
}
public static byte[] StructToBytes(object structObj)
{
//得到结构体的大小
int size = Marshal.SizeOf(structObj);
//创建byte数组
byte[] bytes = new byte[size];
//分配结构体大小的内存空间
IntPtr structPtr = Marshal.AllocHGlobal(size);
//将结构体拷到分配好的内存空间
Marshal.StructureToPtr(structObj, structPtr, false);
//从内存空间拷到byte数组
Marshal.Copy(structPtr, bytes, 0, size);
//释放内存空间
Marshal.FreeHGlobal(structPtr);
//返回byte数组
return bytes;
}
private void TestTcp_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
int ret;
TMsgBody msgbody;
//TMsgHeadInfo msghead;
TCPClient tcp = new TCPClient();
string code = "zp";
string type = "ai";
ret = tcp.ConnectServer("127.0.0.1", 3578);
if (ret == 0)
{
MessageBox.Show("连接服务器失败");
}
else
{
MessageBox.Show("连接服务器成功");
msgbody.msghead[0].MsgCode = code.ToCharArray();
msgbody.msghead[0].MsgType = type.ToCharArray();
msgbody.msghead[0].Sender = 5; string code = "zp11";
string type = "ai11";
msgbody.msghead[1].MsgCode = code.ToCharArray();//这样写,直接提示错误,无法编译
msgbody.msghead[1].MsgType = type.ToCharArray();
msgbody.msghead[1].Sender = 5;
byte[] msg = StructToBytes(msgbody);
if (tcp.SendMsg(msg) > 0)
{
MessageBox.Show("发送成功");
}
else
{
MessageBox.Show("发送失败");
}
}
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using MTWS.Net.SocketClient;
namespace MTWS.Net.AppCode
{
public partial class TestTcp : Form
{
public TestTcp()
{
InitializeComponent();
}
struct TMsgHeadInfo
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char[] MsgCode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char[] MsgType;
public byte Sender;
}
struct TMsgBody
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public TMsgHeadInfo[] msghead;
public Int32 body; //这里哪个类型对就DELPHI里的integer?
}
public static byte[] StructToBytes(object structObj)
{
//得到结构体的大小
int size = Marshal.SizeOf(structObj);
//创建byte数组
byte[] bytes = new byte[size];
//分配结构体大小的内存空间
IntPtr structPtr = Marshal.AllocHGlobal(size);
//将结构体拷到分配好的内存空间
Marshal.StructureToPtr(structObj, structPtr, false);
//从内存空间拷到byte数组
Marshal.Copy(structPtr, bytes, 0, size);
//释放内存空间
Marshal.FreeHGlobal(structPtr);
//返回byte数组
return bytes;
}
private void TestTcp_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
int ret;
TMsgBody msgbody;
//TMsgHeadInfo msghead;
TCPClient tcp = new TCPClient();
string code = "zp";
string type = "ai";
ret = tcp.ConnectServer("127.0.0.1", 3578);
if (ret == 0)
{
MessageBox.Show("连接服务器失败");
}
else
{
MessageBox.Show("连接服务器成功");
msgbody.msghead[0].MsgCode = code.ToCharArray();
msgbody.msghead[0].MsgType = type.ToCharArray();
msgbody.msghead[0].Sender = 5; string code = "zp11";
string type = "ai11";
msgbody.msghead[1].MsgCode = code.ToCharArray();//这样写,直接提示错误,无法编译
msgbody.msghead[1].MsgType = type.ToCharArray();
msgbody.msghead[1].Sender = 5;
byte[] msg = StructToBytes(msgbody);
if (tcp.SendMsg(msg) > 0)
{
MessageBox.Show("发送成功");
}
else
{
MessageBox.Show("发送失败");
}
}
}
}
}
消息头 + 长度 + 数据正文 + 校验位
1Byte 4Bytes N Bytes 1Byte无论你 Byte int long string 还是struct 或者class
全部转换成字节数组 放到数据正文中struct class 序列化
Encoding
Serilize都是转换的好办法
请用BinaryWriter来写数据包
Socket最终发送的都是Byte[],而你结构体里面的这些数据
msgbody.msghead.MsgCode = code.ToCharArray();
msgbody.msghead.MsgType = type.ToCharArray();
msgbody.msghead.Sender = 5;
msgbody.body = 44;// body.ToCharArray();
最后也是生成Byte[]
你知道结构体在C++内存中他这些数据是怎么存的么。
让你用BinaryWrite就是这个意思,生成的Byte[]与你的结构体是一样的,只要按顺序写入对应的值。明白?
转换后整型数值不对要看DELPHI的integer转换成字节数组,是以左高位位移,还以右高位位移
public byte[] StructToBytes(object obj)
{
int size = Marshal.SizeOf(obj);
byte[] bytes = new byte[size];
IntPtr structPtr = Marshal.AllocHGlobal(size); //分配结构体大小的内存空间
Marshal.StructureToPtr(obj, structPtr, false); //将结构体拷到分配好的内存空间
Marshal.Copy(structPtr, bytes, 0, size); //从内存空间拷到byte数组
Marshal.FreeHGlobal(structPtr); //释放内存空间
return bytes;
} msgbody.msghead.MsgCode = code.ToCharArray();
msgbody.msghead.MsgType = type.ToCharArray();
msgbody.msghead.Sender = 5;
msgbody.body = 44;// body.ToCharArray();
Tools tool = new Tools();
byte[] msg = tool.StructToBytes(msgbody); //上面的方法
这边发的body是44,那么收到的确是738197504咋回事
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char[] MsgCode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char[] MsgType;
public byte Sender;
}
struct TMsgBody
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public TMsgHeadInfo[] msghead;
public Int32 body; //这里哪个类型对就DELPHI里的integer?
}这2个结构的DELPHI定义和C#一致吗?它们成员定义的顺序是一致的吗?