一个中压缩了多个套接字消息

时间:2018-10-19 20:27:10

标签: c# node.js multithreading sockets

我正在尝试编写一个从本地NodeJS到C#套接字服务器通信的程序。

这是我正在使用的代码

NodeJS

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

有人对为什么将第一个消息之后的所有消息压缩为一个大消息有想法吗?

1 个答案:

答案 0 :(得分:0)

原因很可能是以下原因(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端可能需要对接收的段进行额外的缓冲。