【发布时间】:2017-04-24 15:40:42
【问题描述】:
我有一个简单的类库,它只包含一种类型。现在我想通过使用套接字将这种类型的实例从客户端发送到服务器。客户端和服务器对我需要加载程序集的 SendingObject 类型一无所知。
[Serializable]
public class SendingObject : MarshalByRefObject
{
public string FirstName { get; set; }
public string LastName { get; set; }
public SendingObject() { }
public SendingObject(string firstname, string lastname)
{
FirstName = firstname;
LastName = lastname;
}
public override string ToString()
{
return string.Format($"Firstname: {FirstName}. Lastname: {LastName}.");
}
}
这是我的客户的代码:
class Program
{
static void Main(string[] args)
{
string path = @"path to MyLibrary.dll";
Assembly library = Assembly.LoadFrom(path);
Type typeObj = library.GetType("MyLibrary.SendingObject");
var sob = Activator.CreateInstance(typeObj, new object[] {"Bob", "Smith"});
try
{
SendAddUserMessageFromSocket(83, sob);
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
}
Console.WriteLine("\nTap to continue...");
Console.ReadKey(true);
}
static void SendAddUserMessageFromSocket(int port, object obj)
{
byte[] brr = ObjectToByteArray(obj);
IPHostEntry ipHost = Dns.GetHostEntry("localhost");
IPAddress ipAddress = ipHost.AddressList[0];
IPEndPoint endPoint = new IPEndPoint(ipAddress, port);
Socket sender = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
sender.Connect(endPoint);
NetworkStream networkStream = new NetworkStream(sender);
if (networkStream.CanWrite)
{
networkStream.Write(brr, 0, brr.Length);
}
Console.WriteLine("The message was sent.");
}
// Convert an object to a byte array
private static byte[] ObjectToByteArray(Object obj)
{
if (obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
return ms.ToArray();
}
// Convert a byte array to an Object
private static Object ByteArrayToObject(byte[] arrBytes)
{
MemoryStream memStream = new MemoryStream();
BinaryFormatter binForm = new BinaryFormatter();
memStream.Write(arrBytes, 0, arrBytes.Length);
memStream.Seek(0, SeekOrigin.Begin);
Object obj = (Object)binForm.Deserialize(memStream);
return obj;
}
}
这个接收到的对象将在服务器端反序列化。这是我的服务器的代码。
class Program
{
static void Main(string[] args)
{
IPHostEntry ipHost = Dns.GetHostEntry("localhost");
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint endPoint = new IPEndPoint(ipAddr, 83);
Socket socketListener = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
string path = @"path to MyLibrary.dll";
Assembly library = Assembly.LoadFrom(path);
Type typeObj = library.GetType("MyLibrary.SendingObject");
try
{
socketListener.Bind(endPoint);
socketListener.Listen(10);
bool isWorkFinished = false;
while (!isWorkFinished)
{
Socket handler = socketListener.Accept();
byte[] bytes = new byte[2064];
// Get data from connected socket to buffer
int numberOfReceivedBytes = handler.Receive(bytes);
byte[] bytesObject = new byte[numberOfReceivedBytes];
for (int i = 0; i < numberOfReceivedBytes; i++)
bytesObject[i] = bytes[i];
object res = ByteArrayToObject(bytesObject);
}
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
}
Console.WriteLine("\nTap to continue...");
Console.ReadKey(true);
}
// Convert an object to a byte array
private static byte[] ObjectToByteArray(Object obj)
{
if (obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
return ms.ToArray();
}
// Convert a byte array to an Object
private static Object ByteArrayToObject(byte[] arrBytes)
{
MemoryStream memStream = new MemoryStream();
BinaryFormatter binForm = new BinaryFormatter();
memStream.Write(arrBytes, 0, arrBytes.Length);
memStream.Seek(0, SeekOrigin.Begin);
Object obj = (Object)binForm.Deserialize(memStream);
return obj;
}
}
我的 SendingObject 可以序列化,但尝试反序列化时出错。
找不到程序集:"MyLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"。
【问题讨论】:
-
2 件事。两个项目都必须使用相同的序列化和反序列化库(例如Me.Packet.Deserializer.dll),这两个项目都必须使用相同版本的外部库。这就是你目前拥有的吗?
-
如果您不从两个项目中引用公共接口 DLL,这确实是您所得到的。 PS:我会避免使用套接字和序列化来处理这样的事情; WCF 很好地完成了这一切。
标签: c# sockets serialization