如何在 C# 中通过 TCP 连接发送整数数组

How to send integer array over a TCP connection in c#

我在 windows 应用程序中建立了两台计算机之间的 TCP 连接,用于来回发送和接收数据。我发送的消息是一组转换为字符串并以“,”分隔的整数。因此,为了发送我要使用的数据,

if (dataSend.Length > 0)
{
    m_writer.WriteLine(dataSend);
    m_writer.Flush();
}

其中dataSend是我的字符串形式的消息,m_writer是一个StreamWriter。

但是,现在我想通过同一网络连接将它作为整数数组发送,但我找不到任何东西。我看到很多人使用字节数组,但我不明白,在阅读时,接收者如何知道如何将字节拆分为相应的整数。

我知道 writeline 方法也允许 Int 作为其参数,但是我如何发送一个数组?
使用字符串很清楚,因为我可以根据“,”分隔数据,所以我知道每个元素将在哪里结束。整数数组的分隔标准是什么?

如果有人能向我解释一下就好了,因为我对 C# 的网络方面也很陌生。

跟进问题:

使用 Encoding.GetBytes(string) 获取字符串的字节数组并使用 Encoding.GetString(byte[]) 转换回字符串。

byte[] arrBytes = Encoding.Default.GetBytes(dataSend);

Converting back to String

string dataRecieved = Encoding.Default.GetString(arrBytes);

这里请注意,您可以使用固定的编码格式,因为发送方和接收方机器上的默认编码可能不同。

好的,您可以使用一个简单的建议

  • 发送方先发送整型数组的长度

  • 接收器创建一个数组来接收这个数据

  • 循环中的发送方使用 WriteLine() 发送数组的每个元素 (作为字符串或整数)

  • 循环中的接收器使用 ReadLine() 来捕获每个元素。并转换 接收到的字符串转整数

发件人:

m_writer.WriteLine(myarray.Length); // Sender sends the array length prior to data transmission

// Send all data
foreach(int item in myarray){
      m_writer.WriteLine(item.ToString());
}

接收者:

int Size =Convert.ToInt32( m_reader.ReadLine()); //receiver receives the Length of incoming array 

int i=0;
// Receive all data
while(i < Size){
     Console.WrilteLine(Convert.ToInt32(m_reader.ReadLine())); // Add this to array
     i++;
}

你问的问题几乎总是会通过使用某种形式的序列化 and/or 数据框架来解决。 IE。 "How do I send some structure over the wire?"

您可能希望使用 XmlSerializer 或 JSON.NET 库等序列化程序将 int[] 序列化为字符串。然后你可以在另一端反序列化。

int[] numbers = new [] { 0, 1, 2, 3};
XmlSerializer serializer = new XmlSerializer(typeof(int[]));
var myString = serializer.Serialize(numbers);

// Send your string over the wire
m_writer.WriteLine(myString);
m_writer.Flush();

// On the other end, deserialize the data
using(var memoryStream = new MemoryStream(data))
{
    XmlSerializer serializer = new XmlSerializer(typeof(int[]));
    var numbers = (int[])serializer.Deserialize(memoryStream);
}

您可以将数据序列化为 XML,但缺点是您最终会为这样一组简单的数字创建一个臃肿的字符串。相反,您应该利用发送原始字节的能力。

要发送一个整数数组,您需要遍历您的整数数组并将每个整数依次写入流中。使用接受整数的 Write 方法。但是您还需要向另一方指示要发送多少个整数。因此,首先发送一个数字,该数字是要跟随的整数计数...

int[] values = new int[] { 1, 2, 3 };
m_writer.Write(values.Length);
foreach(int value in values)
    m_write.Write(value);

在接收方,您读取整数,这就是您需要读取整数以重新创建数组的次数。

int count = m_reader.ReadInt32();
int[] values = new byte[count];
for(int i=0; i<values; i++)
    values[i] = m_reader.ReadInt32();

显然我已经跳过了任何错误检查,但我将其保留为 reader!

的练习量

我将给你一个答案,假设你想要实际传输字节,以保持协议简洁:如果不接受 alexw 答案,因为它是一个非常好的答案。

你应该看看某种形式的 message framing, or at the very least length prefixing。十多年来,我一直在处理 TCP 套接字协议,并且总是使用某种形式的协议(主要是消息框架)。然而,最近我一直在使用 WCF,它使用 (.NET) 序列化,所以我实际上倾向于 alexw 答案,给定无限带宽(和 a .NET 堆栈 一个共同的架构,或者至少是双方商定的序列化算法)。

编辑

使用简单的长度前缀可能会是这样:

var myArray = new byte[10];
using (var stream = new MemoryStream())
using (var writer = new BinaryWriter(stream))
{
    writer.Write(myArray.Length);
    foreach (var b in myArray)
        writer.Write(b);
}

当然,使用这种技术,双方都必须参与其中:您在 TCP 之上建立应用程序级协议,双方必须使用相同的语言(例如,知道长度存储在一个字节中,知道我们只发送简单的字节数组,没有进一步的上下文......请参阅消息框架以了解 "further context" 可能是什么样子)。