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

如何实现C#服务器接收Node.js客户端命令及通信?

Hey there! 我看你正在搭建C# TCP服务器和Node.js客户端的通信链路,现有代码已经搭好了基础的流初始化框架,但还有变量命名一致性、消息收发逻辑、资源释放这些细节需要补全。我来帮你把整个实现流程梳理清楚,附上完整的可运行代码和关键注意事项:

1. 完善C# TCP服务器代码

首先修正你现有代码里的变量命名不一致问题(比如私有字段_controlStream和你后续写的controlStream),然后补充完整的连接监听、消息收发、异常处理和资源释放逻辑:

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

public class TcpServer
{
    private TcpListener _listener;

    // 保持私有字段命名的一致性
    private NetworkStream _controlStream;
    private StreamReader _controlReader;
    private StreamWriter _controlWriter;
    private string _clientIP;

    public void StartServer(int port)
    {
        _listener = new TcpListener(IPAddress.Any, port);
        _listener.Start();
        Console.WriteLine($"TCP Server started, listening on port {port}");

        // 异步接受客户端连接,支持多客户端接入
        _ = AcceptClientsAsync();
    }

    private async Task AcceptClientsAsync()
    {
        while (true)
        {
            try
            {
                var controlClient = await _listener.AcceptTcpClientAsync();
                Console.WriteLine("New client connected");
                
                // 单独开任务处理当前客户端,不阻塞后续连接
                _ = HandleClientAsync(controlClient);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Failed to accept client: {ex.Message}");
                break;
            }
        }
    }

    private async Task HandleClientAsync(TcpClient controlClient)
    {
        try
        {
            var remoteEndPoint = (IPEndPoint)controlClient.Client.RemoteEndPoint;
            _clientIP = remoteEndPoint.Address.ToString();
            Console.WriteLine($"Client IP: {_clientIP}");

            _controlStream = controlClient.GetStream();
            // 指定UTF8编码保证跨语言编码一致,开启AutoFlush避免消息缓存
            _controlReader = new StreamReader(_controlStream, Encoding.UTF8);
            _controlWriter = new StreamWriter(_controlStream, Encoding.UTF8) { AutoFlush = true };

            // 循环接收客户端消息,直到连接断开
            string receivedMsg;
            while ((receivedMsg = await _controlReader.ReadLineAsync()) != null)
            {
                Console.WriteLine($"Received from {_clientIP}: {receivedMsg}");
                // 回复客户端消息
                await _controlWriter.WriteLineAsync($"Server echo: {receivedMsg}");
            }

            Console.WriteLine($"Client {_clientIP} disconnected");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error handling client {_clientIP}: {ex.Message}");
        }
        finally
        {
            // 确保资源被正确释放,避免内存泄漏
            _controlReader?.Dispose();
            _controlWriter?.Dispose();
            _controlStream?.Dispose();
            controlClient?.Dispose();
        }
    }
}

// 启动服务器示例
class Program
{
    static void Main()
    {
        var server = new TcpServer();
        server.StartServer(8888);
        Console.WriteLine("Press any key to stop server...");
        Console.ReadKey();
    }
}

2. 配套Node.js客户端实现

对应C#服务器的消息格式(换行符分隔消息),用Node.js的net模块实现客户端,同时用readline模块提供命令行交互:

const net = require('net');
const readline = require('readline');

// 创建命令行交互实例
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

// 连接到C#服务器
const client = new net.Socket();
client.connect(8888, 'localhost', () => {
    console.log('Successfully connected to C# server');
    promptForMessage();
});

// 接收服务器回复
client.on('data', (data) => {
    console.log(`Server response: ${data.toString().trim()}`);
    promptForMessage();
});

// 处理连接关闭
client.on('close', () => {
    console.log('Connection to server closed');
    rl.close();
});

// 处理网络错误
client.on('error', (err) => {
    console.log(`Network error: ${err.message}`);
    rl.close();
});

// 提示用户输入消息
function promptForMessage() {
    rl.question('Enter message to send (type "exit" to quit): ', (msg) => {
        if (msg.toLowerCase() === 'exit') {
            client.end();
            rl.close();
            return;
        }
        // 发送消息时添加换行符,匹配C#的ReadLine逻辑
        client.write(`${msg}\n`);
    });
}

3. 关键注意事项

  • 消息边界处理:TCP是流协议,我们用换行符\n作为消息分隔符,对应C#的ReadLineAsync和Node.js的行读取逻辑,避免粘包问题;如果需要传输二进制数据,可以改用「消息长度前缀+内容」的格式。
  • 编码一致性:全程统一使用UTF8编码,避免跨语言通信时出现乱码。
  • 多客户端支持:C#服务器用异步任务单独处理每个客户端连接,不会阻塞后续客户端接入。
  • 资源释放:C#中使用Dispose释放流和客户端资源,Node.js中监听连接关闭事件清理资源,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Bing Feng

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:37:30