【问题标题】:Byte[256] over TCP limiting to 5 charactersTCP 上的字节 [256] 限制为 5 个字符
【发布时间】:2014-03-13 12:57:05
【问题描述】:

我在使用 .NET 3.5 (C#) 编写的 TCP 服务器\客户端遇到问题。

每当我使用下面的代码传输数据时,只有 5 个字符会传输到服务器。如何修复我的代码以使我有超过 5 个字符的传输?

TcpClient client = new TcpClient(connectto.ToString(), portto);
Stream s = client.GetStream();
StreamReader sr = new StreamReader(s);
StreamWriter sw = new StreamWriter(s);

Byte[] data = new Byte[256];
data = System.Text.Encoding.ASCII.GetBytes("auth:" + adminPASS.Text);

s.Write(data, 0, data.Length);

data = new Byte[256];

String responseData = String.Empty;

Int32 bytes = s.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);

服务器只获取传输内容的前 5 个字符。其余的都丢失了。

【问题讨论】:

  • 你能验证 adminPASS.Text 不为空吗?写入完成时也调用 s.Flush()。
  • 即使我加了一个保障,保证文本框的值不为空,看来数据还是没有通过。我还有一个带有“已连接”文本的字符串,它在初始连接到服务器时发送。在 Visual Studio 的输出日志中,我得到这个“得到消息连接”,然后直接在它下面得到“得到消息”。我也尝试使用 s.Flush(),但没有任何改变。
  • 你知道你没有发送 Byte[256] 的数据,你创建了一个 256 的大数组,但是当你发送 data = System.Text.Encoding... 时立即将其丢弃,就像你发送 Byte[] data = ystem.Text.Encoding... 一样。跨度>
  • 经过一些测试,我发现只有从客户端发送到服务器的数据丢失了。从服务器到客户端的数据保持不变。

标签: c# .net tcpclient


【解决方案1】:

Stream.Read 可以返回比请求更少的字节,因此您需要循环调用它,直到到达 EOF,如下所示:

int bytes;
int offset = 0;

while ((bytes = s.Read(data, offset, data.Length - offset) != 0)
{
   offset += bytes;
}

此外,您从不Dispose() 您的流,因此它们很可能没有被刷新。在所有 IDisposable 对象周围使用 using statement

【讨论】:

  • 我试过你所说的 Stream.Read 函数的代码......到目前为止,它只导致客户端挂起并停止响应。我还需要将此代码添加到流编写器吗?
  • @themsftcpu 正如他所说,它将循环直到到达 EOF 结束,因此发送者需要关闭连接以停止循环。如果您尝试完全填充 data.Length 字节,您可以在开头添加 offset < data.Length && (bytes = ...
【解决方案2】:
Byte[] data = new Byte[256];  

这分配了 256 个字节

data = System.Text.Encoding.ASCII.GetBytes("auth:" + adminPASS.Text); 

这会丢弃 256 个字节并将 "auth:" + adminPASS.text 转换为字节

s.Write(data 0, data.length)

发送 5 个字节 + adminPASS.text 的长度

看起来您只发送了大约 5 个字节,尤其是当 adminPASS.text 为空时

【讨论】:

  • 这是很好的信息,但丢失的数据很可能是由于缓冲区没有被刷新(参见 John 的回答和 @payo 的评论)。
  • 从标题中可以看出,他希望传输 256 个字节。它肯定不是。你是对的,刷新“可能”有帮助,但不太可能,因为发送很少会分解这么小的消息,所以如果他得到 5 个字节,那么刷新不太可能影响它
【解决方案3】:

您的大多数对象都实现了 IDisposable,因此需要位于 using 块中。

using 块确保调用 Dispose 方法。在这种情况下,Dispose 会刷新缓冲区并等待所有数据发送完毕。

【讨论】:

  • 这听起来更像是评论而不是答案。详细说明缺少对 IDisposable.Dispose() 的调用导致观察到的行为的原因将显着改善答案。
【解决方案4】:

没关系,获取要在服务器上使用的字符串的原始代码是,

mstrMessage = mstrMessage.Substring(0, 5);

所以它只读取前 5 个字节的数据。将此更改为 bytesReceived.Length ,它工作正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-01
    • 2012-07-06
    相关资源
    最近更新 更多