【问题标题】:Multiple socket messages compressed in one多个套接字消息压缩为一个
【发布时间】:2019-03-24 18:22:26
【问题描述】:

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

这是我正在使用的代码

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

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

【问题讨论】:

  • 基本上这就是 TCP 的工作原理。 TCP 为您提供字节流,它不是基于消息的。接收调用可以读取另一端使用 Send() 调用发送的多个或部分数据。

标签: c# node.js multithreading sockets


【解决方案1】:

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

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

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

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

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

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

【讨论】:

  • 谢谢!它解决了我的问题,但现在我有了一个新问题。将setTimeout(() =&gt; client.write('OK'), 3500); 替换为原始操作(正在解决验证码)后,当 NodeJS 客户端收到 2 个由 URL 和 Data SiteKey 组成的请求(用于 google recaptcha's)时,它会解决 2 个请求,然后只发回一个解决方案到服务器,知道为什么吗? hastebin.com/azecajeruc.js
  • @PeterWave 请为您的新问题创建一个新问题。 1. 你会为这个问题获得更多的听众。 2. 其他有相同问题的人可以找到解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-22
  • 1970-01-01
  • 2015-11-17
相关资源
最近更新 更多