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和一些结构体
然后获取结构体数据
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和一些结构体
然后获取结构体数据
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
{ }
}
m_scoket.re.......接收
发送 ID=1000,USERNAME=ADMIN,PASSWORD=888888和一些结构体
然后获取结构体数据 的部分代码,我始终获取不了数据,代码写的很差还要高手帮忙写下中间一部分代码具体是怎么实现的,,谢谢了
现在楼主的问题主要就是怎么把这个结构体发出去,还有就是怎么接收是吗?
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);
}先运行第一个,再运行第二个
现在楼主的问题主要就是怎么把这个结构体发出去,还有就是怎么接收是吗?是的,,我需要的就是怎么发送结构体数据,获取结构体数据
等下我发我写的发送的结构体数据
{
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)
{ }
}
http://hi.baidu.com/yangliangwang/blog/item/1a0116138ff098d6f6039ea9.html
但是理解能力太差。反应慢,,理解不过来
现在你用C#发送结构体成功了吧,是不是就剩在C++接收的时候获取不了了?
_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++ 根据你翻译过来的结构体不对...感觉而已.
/// C#版的 C++结构体
/// </summary>
顶一下
但是这个怎么传送数据参数和结构体,具体的搞不清楚。
这个关键就是C# SOCKET的写法 和 C++结构体,格式化处理,或者数据流操作。
{
//系统登录
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++的结构代码,应该没有写错
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位的