【问题标题】:How to send an object from client to server and reverse?如何将对象从客户端发送到服务器并反向?
【发布时间】:2021-12-04 04:03:25
【问题描述】:

我无法通过 C# 中的套接字发送对象。我想发送一个对象,它有一个字符串和一个名为“MessageType”的类型,其中包含不同消息类型的枚举。这是对象:

public class Message
    {
        public MessageType Type { get; set; }
        public string Content { get; set; }
    }

    public enum MessageType
    {
        Hello,
        Welcome,
        BookInquiry,
        UserInquiry,
        BookInquiryReply,
        UserInquiryReply,
        EndCommunication,
        Error,
        NotFound,
    }

我想发送例如 Type Hello,它的 Content: 'Client 0'。

这是我到目前为止发送的内容:

public Output start()
        {
            int maxBuffSize = 1000;

            byte[] buffer = new byte[maxBuffSize];
            byte[] msg = new byte[maxBuffSize];
            string data = null;
            ConsoleKeyInfo key;


            
            settings.ServerPortNumber = 11111;

            this.serverEndPoint = new IPEndPoint(this.ipAddress, settings.ServerPortNumber);
            

            this.clientSocket = new Socket(AddressFamily.InterNetwork,
                                    SocketType.Stream, ProtocolType.Tcp);

            this.clientSocket.Connect(this.serverEndPoint);

            while (true)
            {
                Console.WriteLine("Connected to server");
                Console.WriteLine("\nSending hello message to server...");
                message.Type = MessageType.Hello;     //Here I specify the type of message
                message.Content = client_id;          //Here I specified the clientID
                Console.WriteLine("Message is", message.Content);
               
                if (message.Content != null)
                {

                    msg = Encoding.ASCII.GetBytes(data);    
                    clientSocket.Send(msg);          //How do I send the object message here?
                    int b = clientSocket.Receive(buffer);
                    data = Encoding.ASCII.GetString(buffer, 0, b);

                    Console.WriteLine("" + data);
                    data = null;
                }

                Console.WriteLine("\n<< Continue 'y' , Exit 'e'>>\n");
                key = Console.ReadKey();
                if (key.KeyChar == 'e')
                {
                    clientSocket.Send(Encoding.ASCII.GetBytes("Closed"));
                    Console.WriteLine("\nExiting.. Press any key to continue");
                    key = Console.ReadKey();
                    clientSocket.Close();
                    break;
                }

            }
            





            return result;
        }

    }

我尝试将消息对象转换为字节数组并发送它,但随后出现无法序列化的错误。我想要一个易于理解的解决方案。我尝试在互联网上搜索,但没有成功。

【问题讨论】:

  • 看看使用protobufs
  • “数据”设置在哪里发送?这是一个序列化的问题。如果需要将对象转换为字符串,反之亦然,则需要序列化器/反序列化器(NewtonJson、.Net Json、XML...)或实现自己的逻辑。

标签: c# sockets


【解决方案1】:

序列化部分可以使用 XML 序列化器完成:

XmlSerializer xs = new(typeof(Message));
using (MemoryStream ms = new())
{
    xs.Serialize(ms, msg);
    var bytes = ms.ToArray();
}

通过 Socket 发送字节数组可以如下完成:

var bytesSent = clientSocket.Send(bytes.AsMemory());
// Caveat: Not all bytes are guaranteed to have been sent

但是,读取该可变大小对象并随后在 TCP 连接的另一端对其进行反序列化要复杂得多。

Socket() 编程存在一百万零一种极端情况,我强烈建议您改用gRPCgRPC services with C#

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-08
    • 1970-01-01
    • 2013-11-16
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多