通过TCP传输的Byte[256]数组限制为5个字符

5

我正在编写一个基于.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个字符,其余内容丢失。


1
你能验证 adminPASS.Text 不为空吗?在写入完成后还要调用 s.Flush()。 - payo
即使我添加了保障以确保文本框的值不为空,似乎数据仍然无法通过。我还有一个包含文本“connected”的字符串,在与服务器的初始连接上发送。在Visual Studio的输出日志中,我得到了“got message conne”,然后直接在其下面得到了“got message”。我还尝试使用s.Flush(),但没有任何变化。 - foxbot
你知道你没有发送 Byte[256] 的数据,你创建了一个 256 大小的数组,但是当你执行 data = System.Text.Encoding... 时,立即将其丢弃,就像你执行了 Byte[] data = System.Text.Encoding... 一样。 - Scott Chamberlain
经过一些测试,我已经发现只有从客户端发送到服务器的数据丢失了。来自服务器到客户端的数据保持完好无损。 - foxbot
4个回答

3

Stream.Read 可能会返回比请求的字节数更少,因此您需要在循环中调用它直到达到 EOF,像这样:

int bytes;
int offset = 0;

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

此外,您从未Dispose()流,因此它们可能没有被刷新。请在所有IDisposable对象周围使用using语句


我尝试了你提供的Stream.Read函数的代码...到目前为止,它只是导致客户端挂起并停止响应。我需要在流写入器中也添加这段代码吗? - foxbot
1
正如@themsftcpu所说,它将循环直到达到EOF的结尾,因此发送方需要关闭连接以停止循环。如果您正在尝试精确填充data.Length字节,则可以在开头添加offset < data.Length && (bytes = ... - Scott Chamberlain

1
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的长度

如果adminPASS.text为空,则似乎只发送了大约5个字节


这是很好的信息,但缺失的数据可能是由于缓冲区未刷新(请参见John的答案和@payo的评论)引起的。 - Eric J.
从标题可以看出,他期望传输256字节。但实际上并不是这样的。你说刷新可能有帮助,但这很不可能发生,因为发送一个如此小的消息被分开的情况很少见,所以如果他只收到了5个字节,那么刷新不太可能对其产生影响。 - NebulaSleuth

0

没关系,用于服务器的字符串获取的原始代码是:

mstrMessage = mstrMessage.Substring(0, 5);

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


0

大多数对象都实现了IDisposable接口,因此需要在using块中使用。

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


1
这听起来更像是一条评论而不是答案。详细阐述缺少对IDisposable.Dispose()的调用导致观察到的行为会显著改善答案。 - Eric J.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接