【发布时间】:2017-01-12 07:17:20
【问题描述】:
我正在研究基于 tcp 的通信协议。我所知 有很多方法可以确定何时结束阅读。
- 在消息结束时关闭连接
- 将消息的长度放在数据本身之前
- 使用分隔符;一些在正常数据中永远不会出现的值(或者总是以某种方式被转义)
通常我会尝试通过 WiFi 网络发送文件(可能不稳定且速度慢)
- RSA 和 AES 通信的原因我不喜欢每次都关闭连接(不能使用 1)
- 这是一个大文件,我无法预测它的长度,所以我无法采取行动 as 方法(不能使用 2)
- 读取时检查特殊内容,写入时转义需要大量过程(不能使用 3)
- 这个方法应该兼容c#和java。
你有什么建议?
更一般的问题:
How to identify end of InputStream in java
C# - TcpClient - Detecting end of stream?
更多信息
我正在编写一个 TCP 客户端服务器通信
首先服务器生成并发送一个RSA公共代码给客户端。
然后客户端会生成 AES(key,IV) 并使用 RSA 加密发回。
到这里一切都很好。
但是我想通过这个网络发送一个文件。这是我当前的数据包 EncryptUsingAES(new AES.IV(16 byte) +file.content(any size))
在服务器中,我无法捕获客户端发送的所有数据。所以我需要知道要读取多少数据 (TcpClient.GetStream().read(buffer , 0 , buffersize) ) 当前代码:
List<byte> message = new List<byte>();
int bytes = -1;
do
{
byte[] buffer = new byte[bufferrSize];
bytes = stream.Read(buffer, 0, bufferrSize);
if (bytes > 0)
{
byte[] tmp = new byte[bytes];
Array.Copy(buffer, tmp, bytes);
message.AddRange(tmp);
}
} while (bytes == bufferrSize);
【问题讨论】:
-
“这是一个大文件,我无法预测它的长度,所以我不能作为方法” - 不要一次发送整个文件,读取几 kB每次并在发送数据包之前插入长度。您必须至少能够知道一定数量的字节,否则您正在尝试的内容几乎是不可能的,不管是否有长度前缀。
-
@VisualVincent 是的,您有权分块阅读,但我也使用 AES,因此很难确定总长度是多少。 AES 添加一些填充取决于模型和配置。并且不同的缓冲区大小使其更加复杂。
-
插入长度之后你已经执行了AES加密,所以你发送加密消息的长度。忽略使用缓冲区以外的任何缓冲区来读取整个消息(“数据包”)。
-
让你的结构看起来像这样:
[Encrypted msg length][Encrypted data]. -
这是@VisualVincent 我无法对大文件执行 AES 的棘手部分,它既耗时又需要内存或硬盘。 2)我想使用动态缓冲区大小导致性能
标签: java c# tcp stream tcpclient