首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用TcpClient未在局域网上完全传输数据

使用TcpClient未在局域网上完全传输数据
EN

Stack Overflow用户
提问于 2013-01-12 17:03:25
回答 1查看 467关注 0票数 2

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

发件人:

  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. int size_of_mydata检索第二条消息的长度
  3. 然后我收到byte[] bytes_of_mydata,知道确切的长度!
  4. 然后我将byte[] bytes_of_mydata转换为string mydata
  5. 反序列化string mydata

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

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

我得到了第二条信息的大小:

代码语言:javascript
运行
复制
int size_of_second_message = BitConverter.ToInt32(dataByteSize, 0); // 55185

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

代码语言:javascript
运行
复制
Byte[] dataByte = new Byte[55185];

但从位置5840开始,我开始接收0(零),所以"5840 - 55185“部分都是"0":

代码语言:javascript
运行
复制
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;

上面的例子来自实际的调试器!

那有什么问题吗?就像传输过程中失去了连接一样!!为什么会发生这种情况,我该如何应对这个问题?它不是在“每次”的基础上发生的。

,下面是代码

发送:

代码语言:javascript
运行
复制
//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();

接收:

代码语言:javascript
运行
复制
//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,读取器。

接收+发送(服务器):

代码语言:javascript
运行
复制
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();

发送+接收(客户端):

代码语言:javascript
运行
复制
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();

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-01-12 17:05:54

TCP是一种基于流的协议,它允许您读取已经接收到的大量数据。仅仅因为您在一个步骤中发送数据,就不能保证数据将在同一个块中接收。你必须在接收端循环,直到你收到所有你预期的数据。

顺便说一句,我认为您的协议在开始时有一个显式的长度字段,它弥补了简单的客户端代码(至少是简单的)。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14295632

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档