シリアル化されたデータをLANネットワーク経由で送信しますが、情報が失われることがあります。プロセスは次のとおりです。
送信者:
string mydata
シリアル化されていますstring mydata
に変換されますbyte[] bytes_of_mydata
int size_of_mydata
の長さですbyte[] bytes_of_mydata
int size_of_mydata
それ自体がbyte[] bytes_size_of_mydata
byte[] bytes_of_mydata
とbyte[] bytes_size_of_mydata
送信されます
受信者:
- 私は最初に受け取ります
byte[] bytes_size_of_mydata
int size_of_mydata
から2番目のメッセージの長さを取得しますbyte[] bytes_size_of_mydata
- 私はそれから受け取ります
byte[] bytes_of_mydata
、正確な長さを知っています! - 次に、に変換
byte[] bytes_of_mydata
しますstring mydata
- デシリアライズ
string mydata
このアプローチは通常ほとんどの状況で機能しますが、データが完全に送信されないことがあるため、文字列を逆シリアル化できません。
byte[]
「レシーバー」で受信したものをデバッグしました。次のようになります。
2番目のメッセージのサイズを取得します。
int size_of_second_message = BitConverter.ToInt32(dataByteSize, 0); // 55185
バイト配列への2番目のメッセージの受信を開始します。
Byte[] dataByte = new Byte[55185];
しかし、位置5840から開始すると、0(null)を受け取り始めるため、「5840-55185」の部分はすべて「0」になります。
byte[5836] = 53;
byte[5837] = 57;
byte[5838] = 54;
byte[5839] = 49;
byte[5840] = 0; // information ends to flow
byte[5841] = 0;
byte[5842] = 0;
byte[5843] = 0;
//....
byte[55185] = 0;
上記の例は、実際のデバッガーからのものです。
だから問題は何ですか?送信中に接続が切れたようです!! なぜそれが起こっているのですか、そしてどうすればこの問題に対処できますか?それは「毎回」発生するわけではありません。
そしてここにコードが来る
送信:
//text_message - my original message
//Nw - network stream
MemoryStream Fs = new MemoryStream(ASCIIEncoding.Default.GetBytes(text_message));
Byte[] buffer = Fs.ToArray(); // total 55185 bytes (as in example)
Byte[] bufferSize = BitConverter.GetBytes(Fs.Length); // 32 bytes represent size
bufferSize = GetNewByteSize(bufferSize);
Nw.Write(bufferSize, 0, bufferSize.Length); // send size
Nw.Flush();
Nw.Write(buffer, 0, buffer.Length); // send message
Nw.Flush();
受け取る:
//get first(SIZE) bytes:
int ReadSize = 0; int maxSize = 32; // 32 - constant!
Byte[] dataByteSize = new Byte[maxSize];
int origsize;
using (var strm = new MemoryStream())
{
ReadSize = Nw.Read(dataByteSize, 0, maxSize);
strm.Write(dataByteSize, 0, ReadSize);
strm.Seek(0, SeekOrigin.Begin);
origsize = BitConverter.ToInt32(dataByteSize, 0); // origsize = 55185
}
Nw.Flush();
//get next(MESSAGE) bytes:
string message = ""; int thisRead = 0;
int max = Convert.ToInt32(origsize); // origsize = 55185
Byte[] dataByte = new Byte[max];
using (var strm = new MemoryStream())
{
thisRead = Nw.Read(dataByte, 0, max);
strm.Write(dataByte, 0, thisRead);
strm.Seek(0, SeekOrigin.Begin);
using (StreamReader reader = new StreamReader(strm))
{
message = reader.ReadToEnd();
}
}
Nw.Flush();
// message - the message that is being transmitted partly (sometimes)!
私はコードを投稿したくありませんでしたが、皆さんは通常「あなたがしたことを見せてください」と尋ねるので、ここにあります!
編集
一時的な修正は、StreamWriter、リーダーに切り替えることです。
受信+送信(サーバー):
NetworkStream Nw = new NetworkStream(handlerSocket.Client);
string toreceive = "";
StreamReader reader = new StreamReader(Nw);
toreceive = reader.ReadLine();
string text_message = "to send back";
StreamWriter writer = new StreamWriter(Nw);
writer.WriteLine(text_message);
writer.Flush();
Nw.Close();
送信+受信(クライアント):
NetworkStream Nw = new NetworkStream(handlerSocket.Client);
StreamWriter writer = new StreamWriter(Nw);
writer.WriteLine("to send");
writer.Flush();
string toreceive = new StreamReader(Nw).ReadLine();
writer.Close();
Nw.Close();
元の問題に関する解決策を探していますが、一時的な修正により、これまでのところすべてが機能しています。