可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have established a TCP connection between two computers for sending and receiving data back and forth, in a windows application. The message that I am sending is a set of integers converted to string and split by ",". So, for sending the data I'd use,
if (dataSend.Length > 0)
{
m_writer.WriteLine(dataSend);
m_writer.Flush();
}
where dataSend is my message in the form of string, and m_writer is a StreamWriter.
But, now I want to send it as an array of integers over the same network connection but I can't find anything for it. I see a lot of people using byte array but with that I don't understand how, at the time of reading, the receiver would know how to split the bytes into the respective integer.
I realize that the writeline method allows for Int as its parameter too, but how do I send an array?
With string it was clear because I could separate the data based on "," and so I knew where each element would end. What would the separation criteria be for integer array?
It would be nice if someone would explain this to me, as I am also fairly new to the networks aspect of C#.
Follow up question: StreamReader does not stop reading C#
回答1:
You're asking a question that will almost always end up being answered by using serialization and/or data framing in some form. Ie. "How do I send some structure over the wire?"
You may want to serialize your int[]
to a string using a serializer such as XmlSerializer or the JSON.NET library. You can then deserialize on the other end.
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);
}
回答2:
Okay a simply suggestion you can use
Sender first send the length of integer array.
Receiver create an array to receive this data
Sender in a loop use WriteLine() to send each element of the array
(As string or int)
Receiver in a loop use ReadLine() to catch each element. and convert
received string to integer
Sender :
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());
}
Receiver :
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++;
}
回答3:
I'm going to give you an answer that assumes you want to actually transmit bytes, to keep the protocol light: if not accept alexw answer instead, because it's a pretty good one.
You should look at some form of message framing, or at the very least length prefixing. I've been dealing with TCP socket protocols for over a decade, and always used some form of this (mostly message framing). Lately, however, I've been using WCF instead, and that uses (.NET) serialization, so I'd actually tend toward alexw answer, given unlimited bandwidth (and a .NET stack a common architecture, or at least an agreed upon serialization algorithm, on both sides).
EDIT
Here's how that might look using simple length prefixing:
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);
}
Of course, using this technique, both parties have to be in on it: you're establishing an Application-Level Protocol on top of TCP, and both sides have to be talking the same language (e.g., knowing that length is stored in a byte, knowing that we're only sending simple arrays of bytes, without further context ... see message framing for what "further context" might look like).
回答4:
You could serialize the data as XML but the down side is you end up creating a bloated string for such a simple set of numbers. Instead you should take advantage of the ability to send raw bytes.
To send an array of integers you would loop over your array of integers and write each one in turn to the stream. Use the Write method that takes an integer. But you also need to indicate to the other side how many integers are going to be sent. So begin by sending a number that is the count of integers to follow...
int[] values = new int[] { 1, 2, 3 };
m_writer.Write(values.Length);
foreach(int value in values)
m_write.Write(value);
On the receiving side you read and integer and then that is the number of times you then need to read integers to recreate the array.
int count = m_reader.ReadInt32();
int[] values = new byte[count];
for(int i=0; i<values; i++)
values[i] = m_reader.ReadInt32();
Obviously I have skipped any error checking, but I leave that as an exersize for the reader!
回答5:
Use Encoding.GetBytes(string)
to get byte array for your string and Encoding.GetString(byte[]) to convert back to string.
byte[] arrBytes = Encoding.Default.GetBytes(dataSend);
Converting back to String
string dataRecieved = Encoding.Default.GetString(arrBytes);
Please note here, you can use a fixed encoding format, as the Default encoding on transmitter and receiver machine can be different.