我正在试着通过发送不同的广播消息来让一个简单的网络程序工作。
First my Message Class:
[Serializable()]
public class Message<T>
{
public enum MessageType
{
Broadcast,
Unicast
}
private T _payload;
private readonly MessageType _type;
private readonly DateTime _createdOn = DateTime.Now;
public MessageType Type
{
get { return _type; }
}
public T Payload
{
get { return _payload; }
set { _payload = value; }
}
public DateTime CreatedOn
{
get { return _createdOn; }
}
private Message() { }
private Message(T setPayload, MessageType type)
{
_payload = setPayload;
_type = type;
}
public class Builder
{
private readonly T _payload;
private MessageType _messageType = MessageType.Unicast;
public Builder(T payload)
{
_payload = payload;
}
public Builder Broadcast()
{
_messageType = MessageType.Broadcast;
return this;
}
public Message<T> Build()
{
Message<T> result = new Message<T>(_payload, _messageType);
return result;
}
}
}然后我有我的课程:
[Serializable()]
public class HelloWorld
{
public String HelloString { get; set; }
public HelloWorld() { }
}
[Serializable()]
class HelloWorld2
{
public String HelloString2 { get; set; }
public HelloWorld2() { }
}现在我有两个方法SendHelloWorld()和SendHelloWorld2()。
我将我的内存流的前32个字节保留给一个包含typeName的字符串。
internal void SendHelloWorld()
{
HelloWorld helloWorld = new HelloWorld();
var message = new Message<HelloWorld>.Builder(helloWorld).Broadcast().Build();
// implement broadcasting
Stream memoryStream = new MemoryStream();
byte[] buffer = ASCIIEncoding.ASCII.GetBytes("Messages.HelloWorld");
memoryStream.Write(buffer, 0, buffer.Length);
SerializationService.Serialize(memoryStream, message);
SendBroadcastMessage(memoryStream);
}SendBroadCastMessage只是将流转换为byte[]并广播消息。
当我收到它们时,我必须检查消息的类型是HelloWorld还是HelloWorld2
但我还没有找到让它工作的方法,字符串不被接受为类型,我也不想使用switch-case,因为之后会添加更多类型的消息。
private void UdpListener()
{
UdpClient listener = new UdpClient(9050, AddressFamily.InterNetwork);
IPEndPoint iep = new IPEndPoint(IPAddress.Any, 9050);
Stream inputStream = new MemoryStream(listener.Receive(ref iep));
byte[] buffer = new byte[32];
inputStream.Read(buffer, 0, 32);
string type = ASCIIEncoding.ASCII.GetString(buffer,0,32);
Message<type> message = _service.Deserialize<Message<HelloWorld>>(inputStream);
Received(message.Payload);
listener.Close();
}发布于 2013-03-06 22:11:33
只需更改UdpListener即可正常工作:
private void UdpListener()
{
_iep = new IPEndPoint(IPAddress.Any, 9050);
_listener = new UdpClient(_iep);
while (true)
{
Stream inputStream = new MemoryStream(_listener.Receive(ref _iep));
dynamic msg = _service.Deserialize<object>(inputStream);
Received(msg.Payload);
}
}感谢你所有的回答
发布于 2013-02-28 00:45:20
问:什么是SerializationService?
希望您使用的是.NET标准序列化,更准确地说是: BinaryFormatter。如果你使用的是SoapFormatter,那么泛型就不会起作用。如果您使用的不是这两个服务,请告诉我们它是什么类型的序列化服务。
如果答案是肯定的(BinaryFormatter),您可以采用以下方法。
建议:
1)创建这个抽象类,并让您的类像这样扩展它:
[Serializable()]
public abstract class AbstractMessage {
public object Payload { get { return this.GetPayload(); } }
protected abstract object GetPayload();
}
[Serializable()]
public class Message<T> : AbstractMessage
{
// .... etc ....
public new T Payload
{
get { return _payload; }
set { _payload = value; }
}
// .... etc ....
protected override object GetPayload() { return this.Payload; }
} 2)停止这样做:
byte[] buffer = ASCIIEncoding.ASCII.GetBytes("Messages.HelloWorld");
memoryStream.Write(buffer, 0, buffer.Length);3)和这个:
byte[] buffer = new byte[32];
inputStream.Read(buffer, 0, 32);
string type = ASCIIEncoding.ASCII.GetString(buffer,0,32);(因为.NET序列化比您以往任何时候都更容易理解,让它为您完成繁重的工作)
4)在您的接收应用程序中,执行以下操作
private void UdpListener()
{
// .... etc ....
//object obj = _service.Deserialize<object>(inputStream);
// this should now work perfectly (as long as you stopped writing the string into stream
// from the client)
object obj = (new BinaryFormatter()).Deserialize(inputStream);
if (!(obj is AbstractMessage))
// complain to yourself via exception, log or other things
var message = obj as AbstractMessage;
object payload = message.Payload;
// here you can access on of two things:
Type payloadType = payload.GetType();
Type aproximatelySameType = message.GetType().GetGenericArguments()[0];
// and you can honor this payload like an object or by casting it to whatever
// you desire, or by reflection, or whatever
Received(message.Payload);
listener.Close();
}发布于 2013-02-28 00:25:16
可以使用静态方法GetType从字符串中获取类型
var myType = Type.GetType("SomeType");但是,除非该类型当前在执行程序集中,否则必须使用fully qualified type name。否则你会得到一个异常。
如果要查看类型的完全限定程序集名称,可以检查类型对象的AssemblyQualifiedName属性。
typeof(HelloWorld).AssemblyQualifiedNamehttps://stackoverflow.com/questions/15116943
复制相似问题