首页 > 解决方案 > 多个套接字消息压缩为一个

问题描述

我正在尝试做一个从本地 NodeJS 通信到 C# Socket 服务器的程序。

这是我正在使用的代码

节点JS

const net = require('net');

class Socket {

    constructor(ip, port) {
        this.ip = ip;
        this.port = port;
    }

    initClient() {
        const client = new net.Socket();

        client.connect(this.port, this.ip, () => {
            console.log(`Connected to ${this.ip}:${this.port}`);
        });

        client.on("data", async data => {
            console.log("Received '" + data.toString() + "'");
            setTimeout(function () {
                client.write("OK");
            }, 3500);

        });

        client.on('close', () => {
            console.log(`Connection closed`);
        });

    }
}

let socket = new Socket("HOST", 1337);
socket.initClient();

C#

主班

List<String> toSendList = new List<String>();
toSendList.Add("TEST 1");
toSendList.Add("TEST 2");
toSendList.Add("TEST 3");
toSendList.Add("TEST 4");
toSendList.Add("TEST 5");

Parallel.ForEach(toSendList, new ParallelOptions { MaxDegreeOfParallelism = 5 }, delegate (string content)
{

    logger.WriteLine("Result => " + socket.SendAndWaitResult(content));

});

服务器套接字类

public Server(int port)
{

    IPEndPoint ip = new IPEndPoint(IPAddress.Any, port);
    Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    socket.Bind(ip);
    socket.Listen(10);

    client = socket.Accept();

}

public String SendAndWaitResult(String content)
{

    byte[] data = new byte[1024];
    data = Encoding.ASCII.GetBytes(content);
    client.Send(data, data.Length, SocketFlags.None);

    data = new byte[1024];
    int receivedDataLength = client.Receive(data);
    string response = Encoding.ASCII.GetString(data, 0, receivedDataLength);

    logger.WriteLine("[DEBUG] Received : '" + response + "'");

    return response;

}

当我运行这两个程序时,这就是我得到的

NodeJS 输出

Connected to HOST:1337
Received 'TEST 1'
Received 'TEST 2TEST 3TEST 4TEST 5'

C# 输出

[DEBUG] Received : 'OK'
Result => OK
[DEBUG] Received : 'OK'
Result => OK

有人知道为什么第一个消息之后的所有消息都压缩成一个大消息吗?

标签: c#node.jsmultithreadingsockets

解决方案


原因很可能是以下(source C# API Send()):

为了提高网络效率,底层系统可能会延迟传输,直到收集到大量传出数据。

因此,即使Send为列表中的每个条目单独调用,操作系统也可能不确定地将它们加入一个 TCP 段。

如果您想区分各个数据项,则应在传输中添加分隔符。例如,在每个项目后使用换行符 ( \n) 并在节点侧拆分它们。

client.on('data', data => data.toString().split('\n').forEach(item => {
  console.log(`Received '${item}'`);
  setTimeout(() => client.write('OK'), 3500);
}));

如果单个传输的大小不适合一个 TCP 段,则可能需要在 Node.js 端对接收的段进行额外的缓冲。


推荐阅读