You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# Socket实现客户端与服务端双向传输自定义对象的方法

C# Socket传输自定义Message对象的实现方案

你之前遇到无法序列化的报错,本质是没有给自定义类配置对应的序列化支持,以下提供两种简单可落地的实现方式:


方案1:JSON序列化(推荐,易调试无额外依赖)

无需修改原有Message类定义,直接用JSON作为中间格式转字节数组,新手不易踩坑,.NET Core 3.0+/.NET 5+自带System.Text.Json库可直接使用,.NET Framework可替换为Newtonsoft.Json实现,逻辑完全一致。

发送端修改

将你原代码中发送部分的逻辑替换为以下内容:

if (message.Content != null)
{
    // 1. 将Message对象序列化为JSON字符串
    string jsonMsg = System.Text.Json.JsonSerializer.Serialize(message);
    // 2. 转成UTF8字节数组(比ASCII支持更全面的字符)
    byte[] msgBytes = System.Text.Encoding.UTF8.GetBytes(jsonMsg);
    // 可选优化:先发4字节的消息长度,解决TCP粘包问题
    byte[] lenBytes = BitConverter.GetBytes(msgBytes.Length);
    clientSocket.Send(lenBytes);
    // 3. 发送实际消息内容
    clientSocket.Send(msgBytes);

    // 接收响应逻辑
    // 先读4字节拿到响应长度
    byte[] lenBuffer = new byte[4];
    clientSocket.Receive(lenBuffer);
    int respLen = BitConverter.ToInt32(lenBuffer, 0);
    // 再读对应长度的响应内容
    byte[] respBuffer = new byte[respLen];
    int received = clientSocket.Receive(respBuffer);
    // 反序列化为Message对象
    string respJson = System.Text.Encoding.UTF8.GetString(respBuffer, 0, received);
    Message respMsg = System.Text.Json.JsonSerializer.Deserialize<Message>(respJson);
    Console.WriteLine($"收到响应:类型={respMsg.Type},内容={respMsg.Content}");
}

接收端对应逻辑

// 接收消息的通用逻辑
byte[] lenBuffer = new byte[4];
socket.Receive(lenBuffer);
int msgLen = BitConverter.ToInt32(lenBuffer, 0);
byte[] msgBuffer = new byte[msgLen];
int receivedCount = socket.Receive(msgBuffer);
string json = Encoding.UTF8.GetString(msgBuffer, 0, receivedCount);
Message receivedMsg = JsonSerializer.Deserialize<Message>(json);

方案2:二进制序列化(性能更高)

适合对传输性能要求较高的场景,需要先给Message类标记可序列化特性:

[Serializable] // 新增这一行即可
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,
}

添加序列化/反序列化工具方法:

// 对象转字节数组
public static byte[] SerializeObj(object obj)
{
    using (MemoryStream ms = new MemoryStream())
    {
        // 注意:.NET 5+默认禁用BinaryFormatter,需要在项目文件里加<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
        System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
        formatter.Serialize(ms, obj);
        return ms.ToArray();
    }
}

// 字节数组转对象
public static T DeserializeObj<T>(byte[] data)
{
    using (MemoryStream ms = new MemoryStream(data))
    {
        System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
        return (T)formatter.Deserialize(ms);
    }
}

发送时直接调用工具方法即可:

byte[] msgBytes = SerializeObj(message);
// 同样建议先发长度再发内容,解决粘包问题
byte[] lenBytes = BitConverter.GetBytes(msgBytes.Length);
clientSocket.Send(lenBytes);
clientSocket.Send(msgBytes);

内容的提问来源于stack exchange,提问作者Poop poop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 15:06:02