using System; using System.IO; using System.Collections; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Serialization;public class App { [STAThread] static void Main() { Serialize(); Deserialize(); } static void Serialize() { // Create a hashtable of values that will eventually be serialized. Hashtable addresses = new Hashtable(); addresses.Add("Jeff", "123 Main Street, Redmond, WA 98052"); addresses.Add("Fred", "987 Pine Road, Phila., PA 19116"); addresses.Add("Mary", "PO Box 112233, Palo Alto, CA 94301"); // To serialize the hashtable and its key/value pairs, // you must first open a stream for writing. // In this case, use a file stream. FileStream fs = new FileStream("DataFile.dat", FileMode.Create); // Construct a BinaryFormatter and use it to serialize the data to the stream. BinaryFormatter formatter = new BinaryFormatter(); try { formatter.Serialize(fs, addresses); } catch (SerializationException e) { Console.WriteLine("Failed to serialize. Reason: " + e.Message); throw; } finally { fs.Close(); } } static void Deserialize() { // Declare the hashtable reference. Hashtable addresses = null; // Open the file containing the data that you want to deserialize. FileStream fs = new FileStream("DataFile.dat", FileMode.Open); try { BinaryFormatter formatter = new BinaryFormatter(); // Deserialize the hashtable from the file and // assign the reference to the local variable. addresses = (Hashtable) formatter.Deserialize(fs); } catch (SerializationException e) { Console.WriteLine("Failed to deserialize. Reason: " + e.Message); throw; } finally { fs.Close(); } // To prove that the table deserialized correctly, // display the key/value pairs. foreach (DictionaryEntry de in addresses) { Console.WriteLine("{0} lives at {1}.", de.Key, de.Value); } } }
需要把这个类设置为可序列化 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.Serialization.Formatters.Binary; using System.IO; namespace Model { public class SerializationUnit { /// <summary> /// 把对象序列化为字节数组 /// </summary> public static byte[] SerializeObject(object obj) { if (obj == null) return null; //内存实例 MemoryStream ms = new MemoryStream(); //创建序列化的实例 BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(ms, obj);//序列化对象,写入ms流中 ms.Position = 0; //byte[] bytes = new byte[ms.Length];//这个有错误 byte[] bytes = ms.GetBuffer(); ms.Read(bytes, 0, bytes.Length); ms.Close(); return bytes; } /// <summary> /// 把字节数组反序列化成对象 /// </summary> public static object DeserializeObject(byte[] bytes) { object obj = null; if (bytes == null) return obj; //利用传来的byte[]创建一个内存流 MemoryStream ms = new MemoryStream(bytes); ms.Position = 0; BinaryFormatter formatter = new BinaryFormatter(); obj = formatter.Deserialize(ms);//把内存流反序列成对象 ms.Close(); return obj; } /// <summary> /// 把字典序列化 /// </summary> /// <param name="dic"></param> /// <returns></returns> public static byte[] SerializeDic(Dictionary<string, object> dic) { if (dic.Count == 0) return null; MemoryStream ms = new MemoryStream(); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(ms, dic);//把字典序列化成流 byte[] bytes = new byte[ms.Length];//从流中读出byte[] ms.Read(bytes, 0, bytes.Length); return bytes; } /// <summary> /// 反序列化返回字典 /// </summary> /// <param name="bytes"></param> /// <returns></returns> public static Dictionary<string, object> DeserializeDic(byte[] bytes) { Dictionary<string, object> dic = null; if (bytes == null) return dic; //利用传来的byte[]创建一个内存流 MemoryStream ms = new MemoryStream(bytes); ms.Position = 0; BinaryFormatter formatter = new BinaryFormatter(); //把流中转换为Dictionary dic = (Dictionary<string, object>)formatter.Deserialize(ms); return dic; } }}
感谢楼上几位,序列化与反序列化解决了,但是有新问题了,接收到的数据多了 直接上代码 public static byte[] GetBinaryFormatData(object msg) { byte[] binaryDataResult = null; MemoryStream memStream = new MemoryStream(); IFormatter brFormatter = new BinaryFormatter(); brFormatter.Serialize(memStream, msg); binaryDataResult = memStream.ToArray(); memStream.Close(); memStream.Dispose(); return binaryDataResult; } public static object RetrieveObject(byte[] binaryData) { MemoryStream memStream = new MemoryStream(binaryData); IFormatter brFormatter = new BinaryFormatter(); Object obj = brFormatter.Deserialize(memStream); return obj; } private void button1_Click(object sender, EventArgs e) { tmsghead msghead = new tmsghead();
msghead.MsgCode = textBox1.Text.ToCharArray(); msghead.Recver = textBox2.Text.ToCharArray(); msghead.Sender = textBox3.Text.ToCharArray(); byte[] msg = GetBinaryFormatData(msghead); TcpClient client = new TcpClient(); IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 7860); client.Connect(ip); if (client.Connected) { client.Client.Send(msg, SocketFlags.None); }
} } [Serializable] public class tmsghead {
public char[] MsgCode; public char[] Sender; public char[] Recver; public tmsghead() { MsgCode = new char[2]; Sender = new char[6]; Recver = new char[6]; } } 服务端的测试程序是delphi写的,用的indy组件unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, IdBaseComponent, IdComponent, IdTCPServer, StdCtrls, Math;type TChar2 = array[0..1] of Char; TChar6 = array[0..5] of Char; TChar32 = array[0..31] of Char; TMsgHead = packed record MsgCode: TChar2; Sender, Recver: TChar6; end; TMsgBody = packed record //msghead: TMsgHead; body: TChar32; end; TForm1 = class(TForm) IdTCPServer1: TIdTCPServer; Memo1: TMemo; Button1: TButton; procedure IdTCPServer1Execute(AThread: TIdPeerThread); procedure Button1Click(Sender: TObject); procedure IdTCPServer1Connect(AThread: TIdPeerThread); procedure IdTCPServer1Disconnect(AThread: TIdPeerThread); private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementation{$R *.dfm}procedure StrToPChar(var ABuf: array of char; ABufLen: Integer; const AStr: string); { 将String转换为PChar,长度不足ABufLen的填充#0 } var Index, LenOfStr: Integer; begin LenOfStr := Length(AStr); for Index := 0 to Min(ABufLen, LenOfStr) - 1 do begin ABuf[Index] := AStr[Index + 1]; end; for Index := LenOfStr to ABufLen - 1 do begin // 长度不足ABufLen的填充#0 ABuf[Index] := #0; end; end;function PCharToStr(ABuf: array of char; ABufLen: Integer): string; { 将PChar(#0结尾)转换为string } var LenOfStr: Integer; begin LenOfStr := Min(ABufLen, StrLen(ABuf)); if LenOfStr <= 0 then begin Result := ''; end else begin SetLength(Result, LenOfStr); Move(ABuf[0], Result[1], LenOfStr); end; end;procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread); var msghead: TMsgHead; msgbody: TMsgBody; begin FillChar(msghead, SizeOf(msghead), 0); if AThread.Connection.Connected then begin AThread.Connection.ReadBuffer(msghead, SizeOf(TMsgHead)); Memo1.Lines.Add(PCharToStr(msghead.MsgCode, SizeOf(msghead.MsgCode))); Memo1.Lines.Add(PCharToStr(msghead.Sender, SizeOf(msghead.Sender))); Memo1.Lines.Add(PCharToStr(msghead.Recver, SizeOf(msghead.Recver))); end; end;procedure TForm1.Button1Click(Sender: TObject); var msghead: TMsgHead; msgbody: TMsgBody; begin IdTCPServer1.Active := True; Memo1.Lines.Add('active'); end;接收到的数据多了,还包括程序集的一些内容 ?MTWS.Net, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null MTWS.Net.AppCode.tmsgheadodeSenderRecver
把char[]转换为string,再用BinaryWriter写入流中.
把char[]转换为string,再用BinaryWriter写入流中. 不用转成string MemoryStream ms = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms); bw.Write(msghead.MsgCode); bw.Write(msghead.Recver); bw.Write(msghead.Sender); ms.ToArray();
http://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.formatters.binary.binaryformatter(v=vs.85).aspx
可以用System.IO.MemoryStream代替上文中的FileStream
using System.IO;
using System.Collections;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;public class App
{
[STAThread]
static void Main()
{
Serialize();
Deserialize();
} static void Serialize()
{
// Create a hashtable of values that will eventually be serialized.
Hashtable addresses = new Hashtable();
addresses.Add("Jeff", "123 Main Street, Redmond, WA 98052");
addresses.Add("Fred", "987 Pine Road, Phila., PA 19116");
addresses.Add("Mary", "PO Box 112233, Palo Alto, CA 94301"); // To serialize the hashtable and its key/value pairs,
// you must first open a stream for writing.
// In this case, use a file stream.
FileStream fs = new FileStream("DataFile.dat", FileMode.Create); // Construct a BinaryFormatter and use it to serialize the data to the stream.
BinaryFormatter formatter = new BinaryFormatter();
try
{
formatter.Serialize(fs, addresses);
}
catch (SerializationException e)
{
Console.WriteLine("Failed to serialize. Reason: " + e.Message);
throw;
}
finally
{
fs.Close();
}
}
static void Deserialize()
{
// Declare the hashtable reference.
Hashtable addresses = null; // Open the file containing the data that you want to deserialize.
FileStream fs = new FileStream("DataFile.dat", FileMode.Open);
try
{
BinaryFormatter formatter = new BinaryFormatter(); // Deserialize the hashtable from the file and
// assign the reference to the local variable.
addresses = (Hashtable) formatter.Deserialize(fs);
}
catch (SerializationException e)
{
Console.WriteLine("Failed to deserialize. Reason: " + e.Message);
throw;
}
finally
{
fs.Close();
} // To prove that the table deserialized correctly,
// display the key/value pairs.
foreach (DictionaryEntry de in addresses)
{
Console.WriteLine("{0} lives at {1}.", de.Key, de.Value);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
namespace Model
{ public class SerializationUnit
{
/// <summary>
/// 把对象序列化为字节数组
/// </summary>
public static byte[] SerializeObject(object obj)
{
if (obj == null)
return null;
//内存实例
MemoryStream ms = new MemoryStream();
//创建序列化的实例
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);//序列化对象,写入ms流中
ms.Position = 0;
//byte[] bytes = new byte[ms.Length];//这个有错误
byte[] bytes = ms.GetBuffer();
ms.Read(bytes, 0, bytes.Length);
ms.Close();
return bytes;
} /// <summary>
/// 把字节数组反序列化成对象
/// </summary>
public static object DeserializeObject(byte[] bytes)
{
object obj = null;
if (bytes == null)
return obj;
//利用传来的byte[]创建一个内存流
MemoryStream ms = new MemoryStream(bytes);
ms.Position = 0;
BinaryFormatter formatter = new BinaryFormatter();
obj = formatter.Deserialize(ms);//把内存流反序列成对象
ms.Close();
return obj;
}
/// <summary>
/// 把字典序列化
/// </summary>
/// <param name="dic"></param>
/// <returns></returns>
public static byte[] SerializeDic(Dictionary<string, object> dic)
{
if (dic.Count == 0)
return null;
MemoryStream ms = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(ms, dic);//把字典序列化成流 byte[] bytes = new byte[ms.Length];//从流中读出byte[]
ms.Read(bytes, 0, bytes.Length); return bytes;
}
/// <summary>
/// 反序列化返回字典
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public static Dictionary<string, object> DeserializeDic(byte[] bytes)
{
Dictionary<string, object> dic = null;
if (bytes == null)
return dic;
//利用传来的byte[]创建一个内存流
MemoryStream ms = new MemoryStream(bytes);
ms.Position = 0;
BinaryFormatter formatter = new BinaryFormatter();
//把流中转换为Dictionary
dic = (Dictionary<string, object>)formatter.Deserialize(ms);
return dic;
}
}}
直接上代码
public static byte[] GetBinaryFormatData(object msg)
{
byte[] binaryDataResult = null;
MemoryStream memStream = new MemoryStream();
IFormatter brFormatter = new BinaryFormatter();
brFormatter.Serialize(memStream, msg);
binaryDataResult = memStream.ToArray();
memStream.Close();
memStream.Dispose();
return binaryDataResult;
} public static object RetrieveObject(byte[] binaryData)
{
MemoryStream memStream = new MemoryStream(binaryData);
IFormatter brFormatter = new BinaryFormatter();
Object obj = brFormatter.Deserialize(memStream);
return obj;
} private void button1_Click(object sender, EventArgs e)
{
tmsghead msghead = new tmsghead();
msghead.MsgCode = textBox1.Text.ToCharArray();
msghead.Recver = textBox2.Text.ToCharArray();
msghead.Sender = textBox3.Text.ToCharArray();
byte[] msg = GetBinaryFormatData(msghead);
TcpClient client = new TcpClient();
IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 7860);
client.Connect(ip);
if (client.Connected)
{ client.Client.Send(msg, SocketFlags.None);
}
}
}
[Serializable]
public class tmsghead
{
public char[] MsgCode;
public char[] Sender;
public char[] Recver;
public tmsghead()
{
MsgCode = new char[2];
Sender = new char[6];
Recver = new char[6];
}
}
服务端的测试程序是delphi写的,用的indy组件unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, IdBaseComponent, IdComponent, IdTCPServer, StdCtrls, Math;type
TChar2 = array[0..1] of Char;
TChar6 = array[0..5] of Char;
TChar32 = array[0..31] of Char;
TMsgHead = packed record
MsgCode: TChar2;
Sender,
Recver: TChar6;
end; TMsgBody = packed record
//msghead: TMsgHead;
body: TChar32;
end; TForm1 = class(TForm)
IdTCPServer1: TIdTCPServer;
Memo1: TMemo;
Button1: TButton;
procedure IdTCPServer1Execute(AThread: TIdPeerThread);
procedure Button1Click(Sender: TObject);
procedure IdTCPServer1Connect(AThread: TIdPeerThread);
procedure IdTCPServer1Disconnect(AThread: TIdPeerThread);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure StrToPChar(var ABuf: array of char; ABufLen: Integer; const AStr: string);
{
将String转换为PChar,长度不足ABufLen的填充#0
}
var
Index, LenOfStr: Integer;
begin
LenOfStr := Length(AStr);
for Index := 0 to Min(ABufLen, LenOfStr) - 1 do
begin
ABuf[Index] := AStr[Index + 1];
end;
for Index := LenOfStr to ABufLen - 1 do
begin
// 长度不足ABufLen的填充#0
ABuf[Index] := #0;
end;
end;function PCharToStr(ABuf: array of char; ABufLen: Integer): string;
{
将PChar(#0结尾)转换为string
}
var
LenOfStr: Integer;
begin
LenOfStr := Min(ABufLen, StrLen(ABuf));
if LenOfStr <= 0 then
begin
Result := '';
end
else
begin
SetLength(Result, LenOfStr);
Move(ABuf[0], Result[1], LenOfStr);
end;
end;procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
msghead: TMsgHead;
msgbody: TMsgBody;
begin
FillChar(msghead, SizeOf(msghead), 0);
if AThread.Connection.Connected then begin
AThread.Connection.ReadBuffer(msghead, SizeOf(TMsgHead));
Memo1.Lines.Add(PCharToStr(msghead.MsgCode, SizeOf(msghead.MsgCode)));
Memo1.Lines.Add(PCharToStr(msghead.Sender, SizeOf(msghead.Sender)));
Memo1.Lines.Add(PCharToStr(msghead.Recver, SizeOf(msghead.Recver)));
end;
end;procedure TForm1.Button1Click(Sender: TObject);
var
msghead: TMsgHead;
msgbody: TMsgBody;
begin
IdTCPServer1.Active := True;
Memo1.Lines.Add('active');
end;接收到的数据多了,还包括程序集的一些内容
?MTWS.Net, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
MTWS.Net.AppCode.tmsgheadodeSenderRecver
把char[]转换为string,再用BinaryWriter写入流中.
把char[]转换为string,再用BinaryWriter写入流中.
不用转成string MemoryStream ms = new MemoryStream();
BinaryWriter bw = new BinaryWriter(ms);
bw.Write(msghead.MsgCode);
bw.Write(msghead.Recver);
bw.Write(msghead.Sender);
ms.ToArray();
class的原始定义 [StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi)] public class testA
{
[MarshalAs(UnmanagedType.ByValArray,SizeConst=2)]
public char[] A;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public char[] B ;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public char[] C;
}封送到byte[]的过程 testA a=new testA();
a.A="aa".ToCharArray();
a.B="bbbbbb".ToCharArray();
a.C="cccccc".ToCharArray();
int res= Marshal.SizeOf(typeof(testA));
byte[] b_array = new byte[res];
IntPtr buff = System.Runtime.InteropServices.Marshal.AllocHGlobal(res);
System.Runtime.InteropServices.Marshal.StructureToPtr(a, buff, true);
System.Runtime.InteropServices.Marshal.Copy(buff, b_array, 0, res);
System.Runtime.InteropServices.Marshal.FreeHGlobal(buff);最终滴b_array就是你要滴