c# - 多个套接字消息压缩为一个
问题描述
我正在尝试做一个从本地 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
有人知道为什么第一个消息之后的所有消息都压缩成一个大消息吗?
解决方案
原因很可能是以下(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 端对接收的段进行额外的缓冲。
推荐阅读
- java - Dynamo DB:UpdateItemSpec:多个更新表达式 - 不工作
- javascript - 如何在我的第二个 div 中显示轮播中的活动图像?
- javascript - 以不同的方法在 javascript 中添加列表
- service-worker - 获取响应流操作
- titanium - Appcelerator Studio 编辑器崩溃
- ios - ObjectMapper 在将对象转换为字典期间删除了没有值的字段
- javascript - Jquery循环调用函数-每次调用时函数不执行
- c++ - c++中使用struct表示缓冲区格式
- bash - 合并不同列的csv文件
- c# - 如何在 C# 中创建通用管道?