gpt4 book ai didi

c# - 数据未使用 TcpClient 在 LAN 上完全传输

转载 作者:太空宇宙 更新时间:2023-11-03 13:49:02 24 4
gpt4 key购买 nike

我通过 LAN 网络发送序列化数据,但有时信息会丢失!流程如下:

发件人:

  1. string mydata 正在序列化
  2. string mydata 转换为 byte[] bytes_of_mydata
  3. int size_of_mydatabyte[] bytes_of_mydata的长度
  4. int size_of_mydata 本身变成了 byte[] bytes_size_of_mydata
  5. byte[] bytes_of_mydatabyte[] bytes_size_of_mydata 被发送

接收方:

  1. 我首先收到 byte[] bytes_size_of_mydata
  2. byte[] bytes_size_of_mydata 中检索第二条消息的长度 int size_of_mydata
  3. 然后我收到 byte[] bytes_of_mydata,知道确切的长度!
  4. 然后我将 byte[] bytes_of_mydata 转换为 string mydata
  5. 反序列化string mydata

这种方式通常适用于大多数情况,但有时我的数据传输不完整,所以无法反序列化字符串。

我已经在“接收器”上调试了接收到的 byte[],下面是发生的事情:

我得到第二条消息的大小:

int size_of_second_message = BitConverter.ToInt32(dataByteSize, 0); // 55185

我开始接收到字节数组的第二条消息:

Byte[] dataByte = new Byte[55185];

但从位置 5840 开始,我开始接收 0(空值),因此“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,reader。

接收 + 发送(服务器):

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();

我正在寻找有关原始问题的解决方案,但由于临时修复,到目前为止一切正常。

最佳答案

TCP 是一种基于流的协议(protocol),可让您读取已接收到的数据。仅仅因为你一步发送数据,并不能保证数据会在同一个 block 中被接收到。您必须在接收方循环,直到您收到所有预期的数据。

顺便说一下,我认为你的协议(protocol)在开头有一个明确的长度字段非常好,它弥补了简单的客户端代码(至少尽可能简单)。

前段时间我问了一个关于等待 X 字节数据可用的内置功能的问题:.NET blocking socket read until X bytes are available? .很遗憾,答案是否定的。

关于c# - 数据未使用 TcpClient 在 LAN 上完全传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14295632/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com