我正在尝试使用C#中的套接字在网络上发送任意对象。
我已经习惯Java及其工作原理,这是C#的新手。 在Java中,我可以创建一个Socket,创建一个OutputObjectStream,然后仅发送对象。我不需要担心序列化。
另一方面,我还有一个套接字,创建一个ObjectInputStream,读取对象,然后将其转换回原始类型。
Java示例:
ObjectInputStream inFromClient = new ObjectInputStream (socket.getInputStream());
Object read = inFromClient.readObject();
if(read instanceof bool) {
// cast read to bool, and call relevant method
} else if(read instanceof UserInfo) {
// cast read to UserInfo...
} else if(read instanceof CarInfo) {
// cast read to CarInfo...
}
但是在C#(我正在使用JSON)中,据我所知,我需要先将Object转换为JSON,然后转换为byte [],然后将其发送。另一方面,我从byte []转换为字符串,然后转换为JSON。我使用DataContractJsonSerializer,它需要知道我希望再次退出哪个对象。但是我没有这些信息。
我当前的解决方案是每次发送两次。发送的第一个对象是方法名称(表示为枚举),发送的第二个对象是实际对象。基于第一个收到的方法名称,我知道第二个对象应该是什么,并且可以将此告知我的JSON序列化程序包装器。像这样:
public static T FromJSON<T>(string json) {
var ms1 = new MemoryStream(Encoding.ASCII.GetBytes(json));
DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(T));
T sm1 = (T) dataContractJsonSerializer.ReadObject(ms1);
return sm1;
我可能可以优化一点,并创建一个包装类,例如SocketMessage,它将保存枚举方法名称,以及一个string类型的参数来保存JSON字符串。但这真的是这样做的方法吗?
是否没有像Java那样的“简单”解决方案?
不一定是套接字,但这就是我所熟悉的。我只需要一台运行服务器的计算机,然后在它旁边的一台计算机运行客户端,因此可以使用套接字以外的其他方法。他们将位于同一网络上,所以我认为没有花哨的Webstuff。我需要一个开放的双向连接。
答案 0 :(得分:2)
您可以做一些事情来简化此操作:
DataContractSerializer
更易于使用。另外,您可以:TypeNameHandling.Object
。 (出于安全考虑,您不应该使用它在网络外进行通信)将它们放在一起:
// 'client' side
using (var socket = new Socket(SocketType.Stream, ProtocolType.IPv6))
using (var networkStream = new NetworkStream(socket))
using (var writer = new StreamWriter(networkStream))
using (var jsonWriter = new JsonTextWriter(writer))
{
socket.Connect("localhost", 8888);
var user = new UserInfo { Name = "Jesse de Wit" }; // That's me
var settings = new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.Objects
};
var serializer = JsonSerializer.Create(settings);
serializer.Serialize(jsonWriter, user);
}
// 'server' side
using (var socket = new Socket(SocketType.Stream, ProtocolType.IPv6))
using (var networkStream = new NetworkStream(socket))
using (var reader = new StreamReader(networkStream))
using (var jsonReader = new JsonTextReader(reader))
{
socket.Accept();
var settings = new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.Objects
};
var serializer = JsonSerializer.Create(settings);
// Note that obj will be a JObject if no type information is included.
object obj = serializer.Deserialize(jsonReader);
if (obj is UserInfo user)
{
// Jesse de Wit
Console.WriteLine(user.Name);
}
}
答案 1 :(得分:0)
通过使用newtonsoft库,在c#中通过JSon Parse甚至可以在{#1}}中使用dynamic
,因此可以按原样对字符串进行序列化,另一方面,您可能可以理解类型是通过查看对象的关键属性来实现的。