2

标题有点长,不过...

我一直在查看这些示例,特别是关于将消息大小写入和读取到字节流的部分
http://doc.trolltech.com/4.4/network-fortuneclient-client-cpp.html
http:// /doc.trolltech.com/4.4/network-fortuneserver-server-cpp.html

但我似乎无法在 C# 中弄清楚。

StreamWriter writer = new StreamWriter(tcpClient.GetStream());
writer.Write(data.Length + data);

这根本不工作。有人可以在正确的方向上轻推我吗?

4

6 回答 6

2

通常你会先发送长度。两端应该就长度的样子达成一致——例如,您可能乐于使用固定的 4 字节长度前缀作为二进制:

  byte[] data = ...
  int len = data.Length;
  byte[] prefix = Bitconverter.GetBytes(len);
  stream.Write(prefix, 0, prefix.Length); // fixed 4 bytes
  stream.Write(data, 0, data.Length);

显然,调用者需要做同样的事情——即读取前 4 个字节以获得长度。对于读取,接收器应注意不要读取太多数据。一种方法是使用限制流 - 例如,此类可用于获取不会读取太多的 Stream。

如果您不希望总是发送 4 个字节的开销,那么可以使用一些更有趣的编码 - 例如,使用 msb 作为延续块。

对于信息,protobuf-net是围绕 Google 的“协议缓冲区”基于消息的格式设计的二进制序列化程序。它为您处理了很多细节,如果您不想花大量时间编写序列化代码,它可能会很有趣。QuickStart 项目中有套接字的示例,例如这里

于 2008-10-15T07:43:36.063 回答
1

而不是data.Length,尝试:

writer.Write(chr(data.Length) + data);

这将为每个数据块添加一个字节作为其长度的前缀(最多 255 个字节长)。正如你所要求的,这只是一个轻推。:)

更新:我只记得 C# 都是 Unicode 之类的东西,所以 chr() 可能给你不止一个字节。调整以适应。

于 2008-10-15T07:18:43.820 回答
1

我想这应该这样做:(我假设你的数据是一个字符串)

流流 = tcpClient.GetStream();
编码编码 = Encoding.GetEncoding("编码名称");

byte[] bytes = encoding.getBytes(data);

stream.Write(BitConverter.GetBytes((short)bytes.Length),0,2); // 希望数据不再是 64k
流。写入(字节,0,字节。长度);
于 2008-10-15T07:36:16.687 回答
0

当您说“这根本不工作”时,我会特别好奇什么不工作。它们是套接字两端的 .NET 应用程序吗?如果是这样,请忽略此答案。如果不是,那么问题可能出在整数的字节顺序上吗?小端与大端的问题?这个线程在这里讨论它:

http://bytes.com/forum/thread225649.html

http://books.google.com/books?id=2zT5b2BS1OUC&pg=PA64&lpg=PA64&dq=c%23+sockets+integers+byte+ordering&source=web&ots=_ISzZZ6HHT&sig=tUHdNT0NGv0uxusmHG9YjFw6j9k&hl=en&sa=X&oi=book_result&resnum=2&ct=result

如果两端都不是 .NET,另一个问题可能是另一端需要 ANSI 字符串,而您正在发送 Unicode。

于 2008-10-15T08:26:00.613 回答
0

如果您想保留它的纯文本性,您还可以指定特定的最大大小并通过 string.Format 填充数字。(例如,长度中只允许 4 个字符)这避免了有用数据流中的数字问题,也简化了解码。

最终的明文解决方案是在长度和数据之间放置一个特定字符,例如 -,然后一次抓取单个字符,直到遇到减号,解码检索到的字符串(当然忽略减号),然后使用它来确定剩余字符串的长度,以及只需要更改以在其间添加该字符的输出代码。

于 2008-10-15T08:52:56.440 回答
0

使用 WriteLine 代替 Write,使用 ReadLine 代替 Read...

如果您正在谈论发送纯文本消息,请在消息末尾附加换行符。然后,读取字节直到遇到这个换行符并将字节转换为字符串。为方便起见,任何 System.IO.StreamReader 和 System.IO.StreamReader 在单个方法(WriterLine 或 ReadLine)中实现此行为 writer.WriteLine("Line to send"); 字符串 lineSent = reader.ReadLine();

于 2009-03-02T23:13:38.953 回答