c# - 有没有更好的方法通过套接字发送 int 列表?

标签 c# sockets serialization asynchronous deserialization

我想通过 tcp 发送一个整数列表(可以是 10 到 1000 个整数)

在解析数据之前,我会向客户端发送它应该接收多少字节。

我还使用 BeginSend/BeginReceive 模式(每个一个线程)。

我想出了这个简单的代码来做我想做的事

const int sizeOfInt = sizeof(int);
int index = 0;

var OriginalList = new List<int>();
OriginalList.Add(1);
OriginalList.Add(42);
//.....
OriginalList.Add(9001);


//prepare and send the ArrayOfByte over the wire
var ArrayOfByte = new byte[OriginalList.Count * sizeOfInt];

foreach (var item in OriginalList)
{
    Array.Copy(BitConverter.GetBytes(item), 0, ArrayOfByte, index, sizeOfInt);

    index += sizeOfInt;
}
//socket.BeginSend(ArrayOfByte....


//socket.BeginReceive(ArrayOfByte....
//On receive move it into a List<int>
int length = ArrayOfByte.Length;

var CopyOfList = new List<int>(length / sizeOfInt);

for (index = 0; index < length; index += sizeOfInt)
{
    CopyOfList.Add(BitConverter.ToInt32(ArrayOfByte, index));
}

有没有更好/更快的方法来做到这一点?

最佳答案

想法:

创建了一个很多不必要的小byte[]实例来收集; BitConverter API 有点麻烦,但可以避免;我可能只使用位操作(shift/and)来写入字节,因为这避免了 CPU 字节顺序问题,但也可以非常有效地使用 unsafe 来完成; BinaryWriter 也可以工作

CPU字节顺序

您实际上不需要为所有内容使用 byte[];您可以按顺序写入,但请注意,如果您禁用了套接字缓冲(NoDelay 等),您可能需要考虑什么是数据包的合理大小

如果您了解有关可能的整数的更多信息,则可能会有更有效的表示形式 - 例如,“varint”编码(基本上,类似于 UTF-8 如何将低位字符编码为单个字节,并使用多字节来表示高位字符字符)

为了消费者有效地处理数据,您还应该发送元素的数量或元素的有效载荷大小,以便接收者知道何时收到逻辑帧 - 除非套接字上只有一条消息


一些基于位操作的套接字代码示例:

int index = 0;
foreach(var val in list) {
    buffer[index++] = (byte)val;
    buffer[index++] = (byte)(val >> 8);
    buffer[index++] = (byte)(val >> 16);
    buffer[index++] = (byte)(val >> 24);

    if(index == buffer.Length) { // flush buffer
        socket.Write(buffer, 0, index);
        index = 0;
    }
}
if(index != 0) { // final flush
    socket.Write(buffer, 0, index);
}

读取代码在开始之前需要保证有一些整数值,然后:

while(index < availableBytes) {
    int val = buffer[index++] | (buffer[index++] << 8)
            | (buffer[index++] << 16) | (buffer[index++] << 24);
    list.Add(val);
}

关于c# - 有没有更好的方法通过套接字发送 int 列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29100768/

相关文章:

c# - 通用属性比较 - 识别属性变化

java - DatagramSocket 关闭后端口仍在使用

java - 用于有状态 kiesession 的 Drools Spark Streaming 集成

c#数值多项式回归

c# - 对于静态成员,C# 中是否有等效于 'this' 的内容?

c# - 动态 T-SQL 的 .NET 错误

c++ - 从单独的线程发送 UDP

javascript - 套接字IO : Client side 'connect' event not firing when socket is already setup

c# - 通过 WCF 发送元组对象?

.net - 如何序列化邮件消息?