using System.Collections;
using System.Collections.Generic;
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Reflection;
using System.Runtime.InteropServices;
namespace ConsoleApplication13
{
public class ByteConvertHelper
{
/// <summary>
/// 将结构体对象转换为byte数组
/// </summary>
/// <param name="obj">被转换对象</param>
/// <returns>转换后byte数组</returns>
public static byte[] Object2Bytes(object obj)
{
int size = Marshal.SizeOf(obj);//获取对象的非托管大小
byte[] bytes = new byte[1024];
IntPtr structPtr = Marshal.AllocHGlobal(size);//从进程的非托管内存中分配内存
Marshal.StructureToPtr(obj, structPtr, false);//将数据从托管内存中封送到非托管内存中
Marshal.Copy(structPtr, bytes, 0, size);//将数据从非托管内存指针复制托管整数数组中
Marshal.FreeHGlobal(structPtr);//释放内存
return bytes;
}
/// <summary>
/// 将byte数组转换成对象
/// </summary>
/// <param name="buff">被转换byte数组</param>
/// <param name="typ">转换成的类名</param>
/// <returns>转换完成后的对象</returns>
public static object Bytes2Object(byte[] buff, Type type)
{
int size = Marshal.SizeOf(type);
if (size > buff.Length)
{
return null;
}
IntPtr structPtr = Marshal.AllocHGlobal(size);//开辟内存
Marshal.Copy(buff, 0, structPtr, size);//
object obj = Marshal.PtrToStructure(structPtr, type);//将数据从非托管内存块封送到新分配的指定类型的托管对象。
Marshal.FreeHGlobal(structPtr);//释放内存
return obj;
}
}
}
结构体数据定义
//下面是结构体的类定义
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace ConsoleApplication12
{
public enum CurrentStatus
{
Serching,
Playing,
Free,
}
public enum PlayerSide
{
Left,
Right,
}
public class PlayerData
{
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] //必须要写,保证结构体的保存在内存中的方式
public struct PlayerStat
{
public float PositionX;
public float PositionY;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] //必须要写,不然字符串没法解析
public string Name;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string SendId;
public CurrentStatus status;
public PlayerSide side;
}
}
}
服务端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
namespace ConsoleApplication13
{
class Program
{
static void Main(string[] args)
{
Socket Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint sIPEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8000);
Server.Bind(sIPEndPoint);
Server.Listen(10);
Socket client = Server.Accept();
byte[] Buff = new byte[1024];
client.Receive(Buff);
PlayerData.PlayerStat data = (PlayerData.PlayerStat)ByteConvertHelper.Bytes2Object(Buff, typeof(PlayerData.PlayerStat));
float x = data.PositionX;
}
}
}
客户端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Reflection;
using System.Runtime.InteropServices;
namespace ConsoleApplication12
{
class Program
{
struct SendMsg
{
public SendMsg(string Begion, double cTestItem1, double cTestItem2, string End)
{
begin = Begion;
TestItem1 = cTestItem1;
TestItem2 = cTestItem2;
end = End;
}
public string begin;
public double TestItem1;
public double TestItem2;
public string end;
}
static void Main(string[] args)
{
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint theIPEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8000);
client.Connect(theIPEndPoint);
PlayerData.PlayerStat data = new PlayerData.PlayerStat();
data.PositionX =3.15f;
data.PositionY = 3.25f;
data.Name = "Name";
data.SendId = "123";
data.status = CurrentStatus.Free;
data.side = PlayerSide.Right;
byte[] byteData = ByteConvertHelper.Object2Bytes(data);
client.Send(byteData);
}
}
}