gpt4 book ai didi

c# - 如何在 C# 中通过网络发送任意对象

转载 作者:行者123 更新时间:2023-12-03 11:59:11 24 4
gpt4 key购买 nike

我正在尝试使用 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,它将保存枚举方法名称,以及一个字符串类型的参数来保存 JSON 字符串。但这真的是这样做的方法吗?

没有像Java那样的“简单”解决方案吗?

它不一定需要是套接字,但这就是我所熟悉的。我只需要一台运行服务器的计算机,以及一台运行客户端的计算机,所以除了 Sockets 之外的其他东西也可以工作。他们将在同一个网络上,所以我认为没有花哨的网络。我需要一个开放的双向连接。

最佳答案

您可以做几件事来使这更容易一些:

  • 将套接字包裹在 NetworkStream 中.这允许您读取/写入流,并使序列化接口(interface)更容易一些。
  • 使用Newtonsoft.Json将您的对象序列化到 json 和从 json 序列化。我发现它比 DataContractSerializer 更容易使用。 .另外,您还可以:
  • 在您的序列化对象中包含类型信息。使用Newtonsoft.Json时,如果序列化中包含类型信息,反序列化时不需要提前知道类型。为此,设置 TypeNameHandlingTypeNameHandling.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);
    }
    }

    关于c# - 如何在 C# 中通过网络发送任意对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56804667/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com