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

C# Socket广播数据时出现传输连接写入失败问题求助

C# TCP服务端向前端广播数据报错及前端无接收问题排查与修复

核心问题分析

  • Connected属性判断失效:Socket.Connected仅反映最近一次IO操作的状态,连接断开后不会自动更新,导致循环继续尝试发送数据触发错误。
  • TCP数据边界未定义:直接发送原始JSON字节流,前端无法区分完整的消息单元,无法正确解析数据,进而主动断开连接,引发"连接被中止"的错误。
  • 资源未正确清理:发送异常后未关闭连接和流,导致资源泄漏;代码中socketInformation为未定义变量,属于语法错误。

修复方案与代码调整

1. 定义消息边界,解决TCP粘包问题

在每个JSON消息前添加消息长度(4字节的Int32),让前端先读取长度,再读取对应长度的字节,确保能解析完整消息。

2. 替换不可靠的Connected判断,改用IO操作结果检测连接状态

通过发送/接收操作的返回值或异常来判断连接是否有效,而非依赖Connected属性。

3. 修正代码错误,完善资源清理

  • 替换未定义的socketInformation为socket;
  • 使用using语句自动管理NetworkStream和Socket资源;
  • 发送异常后立即终止循环并清理连接。

修改后的完整代码

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

class TcpBroadcaster
{
    static void Main()
    {
        Socket listenerSocket = new Socket(
            AddressFamily.InterNetwork,
            SocketType.Stream,
            ProtocolType.Tcp
        );

        listenerSocket.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 15001));
        listenerSocket.Listen(10);
        listenerSocket.SendTimeout = 5000;
        listenerSocket.ReceiveTimeout = 5000;
        listenerSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
        listenerSocket.NoDelay = true;

        Console.WriteLine("Waiting for Connection .....");
        while (true)
        {
            // 等待新连接
            using Socket acceptedConnection = listenerSocket.Accept();
            using NetworkStream stream = new NetworkStream(acceptedConnection);
            Console.WriteLine("Client connected. Starting transmission...");

            bool isConnected = true;
            while (isConnected)
            {
                Console.WriteLine("Transmitting Feed ..");
                try
                {
                    // 准备JSON数据
                    string jsonContent = PrepareMarkertDataToJSON(data); // 假设data是你的数据源
                    byte[] jsonBytes = Encoding.UTF8.GetBytes(jsonContent);

                    // 先发送消息长度(4字节,大端格式适配多数前端)
                    byte[] lengthBytes = BitConverter.GetBytes(jsonBytes.Length);
                    if (!BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(lengthBytes);
                    }
                    stream.Write(lengthBytes, 0, lengthBytes.Length);

                    // 发送JSON数据
                    stream.Write(jsonBytes, 0, jsonBytes.Length);
                    stream.Flush(); // 确保数据写入网络

                    Thread.Sleep(1000);
                }
                catch (SocketException ex)
                {
                    Console.WriteLine($"Connection error: {ex.Message}");
                    isConnected = false;
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error: {ex.Message}");
                    isConnected = false;
                }
            }

            Console.WriteLine("Client disconnected. Waiting for new connection...");
        }
    }

    // 模拟数据序列化方法,替换为你的实际逻辑
    static string PrepareMarkertDataToJSON(object data)
    {
        return "{\"data\": \"sample market data\"}";
    }
}

前端适配要点

前端接收数据时,需要先读取4字节的长度,再读取对应长度的字节,再转为JSON(Node.js TCP客户端示例):

const net = require('net');
const client = net.connect({ port: 15001, host: '127.0.0.1' }, () => {
  console.log('connected to server');
});

let buffer = Buffer.alloc(0);
client.on('data', (data) => {
  buffer = Buffer.concat([buffer, data]);
  
  // 循环处理完整消息
  while (buffer.length >= 4) {
    const length = buffer.readInt32BE(0); // 和后端大端格式对应
    if (buffer.length >= 4 + length) {
      const jsonBuffer = buffer.slice(4, 4 + length);
      const json = JSON.parse(jsonBuffer.toString('utf8'));
      console.log('Received data:', json);
      
      // 截断buffer,处理剩余数据
      buffer = buffer.slice(4 + length);
    } else {
      break; // 数据不足,等待下一次接收
    }
  }
});

client.on('end', () => {
  console.log('disconnected from server');
});

额外注意事项

  • 若前端使用WebSocket而非原生TCP,建议后端直接使用ASP.NET Core WebSocket服务,避免手动处理TCP消息边界;
  • 超时时间设置无需过大,5秒左右足够,过长会导致无效连接占用资源;
  • 生产环境建议使用异步IO(AcceptAsync、WriteAsync),避免阻塞主线程。

内容的提问来源于stack exchange,提问作者Kinyua James

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 01:45:44