我想做的是 将一个自定义对象序列化后传输到网络的另一边,然后在接收端再反序列化
//客户端代码如下
public class ClientControlManager
{
#region 单例
static ClientControlManager instance;
public static ClientControlManager Instance
{
get
{
if (instance == null)
instance = new ClientControlManager();
return instance;
}
}
private ClientControlManager() {}
#endregion
Socket _clientSocket;
/// <summary>连接服务器</summary>
public void ConnectionServer()
{
_clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_clientSocket.NoDelay = true;
IPAddress ipAddress = IPAddress.Parse(Config.ipAddress);
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, Config.portId);
_clientSocket.BeginConnect(ipEndPoint, ConnetCallback, _clientSocket);//
}
private void ConnetCallback(object resultObj)
{
Console.WriteLine("连接服务器成功.....................");
DataTest dt = new DataTest();
dt.i1 = 3;
dt.i2 = 4;
dt.f = 5.6f;
SendMsg(dt);
}
/// <summary>
/// 发送消息
/// </summary>
public void SendMsg(object msg)
{
Console.WriteLine("发送消息到服务器................");
using (MemoryStream memory = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(memory, msg);
Console.WriteLine("发送长度:" + memory.ToArray().Length);
_clientSocket.Send(memory.ToArray());
}
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("客户端开启");
ClientControlManager.Instance.ConnectionServer();
Console.ReadLine();
}
}
//服务器端代码如下:
public class NetworkControlManager
{
# region 单例
static NetworkControlManager _instance;
public static NetworkControlManager Instance
{
get
{
if (_instance == null)
_instance = new NetworkControlManager();
return _instance;
}
}
private NetworkControlManager(){}
#endregion
Socket _serverSocket; //服务套接字
/// <summary>初始化服务</summary>
public void InitService()
{
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_serverSocket.NoDelay = true;
IPAddress idAddress = IPAddress.Parse("127.0.0.1");//服务器主机地址
_serverSocket.Bind(new IPEndPoint(idAddress, Config.portID));
_serverSocket.Listen(50);
Console.WriteLine("开启服务器...............");
Thread listenThread = new Thread(ListenClient);
listenThread.Start();
}
/// <summary>开启的一个线程,监听客户端</summary>
private void ListenClient()
{
Console.WriteLine("监听客户端.......................");
while (true)
{
Socket clientSocket= _serverSocket.Accept();//阻塞状态
Thread clientThread = new Thread(HandleClient);
clientThread.Start(clientSocket);
}
}
/// <summary>每个客户端都在这里处理,这里是多线程</summary>
private void HandleClient(object clientSocketObj)
{
byte[] result = new byte[1024];
Socket ClientSocket = clientSocketObj as Socket;
List<byte> listByte = new List<byte>();
try
{
while (true)
{
int byteCount = ClientSocket.Receive(result);
if (result.Length == byteCount)
listByte.AddRange(result);
else
{
for (int i = 0; i < byteCount; i++)
listByte.Add(result[i]);
break;
}
}
using (MemoryStream m = new MemoryStream(listByte.ToArray()))
{
BinaryFormatter bf = new BinaryFormatter();
Console.WriteLine("m.length" + m.ToArray().Length);
object dataObj = bf.Deserialize(m);
DataTest dt = dataObj as DataTest;
Console.WriteLine("接收客户端长度:" + listByte.Count+" i1:" + dt.i1 + " i2:" + dt.i2 + " f:" + dt.f);
}
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
}
}
}
class Program
{
static void Main(string[] args)
{
NetworkControlManager.Instance.InitService();
}
}
//自定义类型
[Serializable]
public class DataTest
{
public int i1;
public int i2;
public float f;
}
注意:
1.序列化对象的class必须要声明为[Serializable]
MemoryStream memory = new MemoryStream()
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(memory, msg);//否则这里会序列化失败,抛出异常
2.序列化对象的类如果分别是在客户端和服务器端自定定义,在接收端反序列化的时候会反序列化失败,我的解决方法是把这个class生成一个dll文件,然后两端都使用这个dll文件的class. 我确实弄不懂谷歌的protocol Buffer的自定义class是怎么做到这一点的
3.生成自定义类型dll
新建一个项目选择创建类库,完成编码后,在项目上右击->生成 然在项目文件夹里找到生成的dll文件,将这个文件引用到服务器端和客户端就可以了