编辑:我对这个问题没有得到足够的回应,可能是我无法正确解释。让我试着解释一下这个问题的背景。
每个屏幕共享程序都有两方。服务器和查看器。
服务器
服务器的角色
- 捕获桌面屏幕
- 将捕获屏幕与之前发送的屏幕进行比较
- 计算脏区 将脏区转换为字节数组
- 将字节数组发送到 TCP 套接字到查看器
观众
查看者的角色
- 从服务器接收字节
- 将字节转换为图像
- 将图像绘制到查看器图片框/面板
要解决的问题
- 有许多重复的区域/区域服务器发送,以前是 向后 10/20 帧发送给查看器。我想使用哈希来避免这种情况。
以下是我的分析
我正在研究屏幕传输应用程序如何像团队查看器,任何办公桌工作并确定它们如何在非常低带宽的互联网连接中很好地工作。
在学习期间,我遇到了屏幕共享应用程序Any Desk。它使用xxHash对图像进行哈希处理,并将图像字节数据与他的哈希代码一起发送。
我在移动互联网上使用网络速度监视器并启动了应用程序。
我反对在桌面上多次执行相同的活动(例如打开/关闭同一目录,最小化和最大化任何应用程序.app除了第一个请求外,不会向客户端发送任何数据/区域。 我假设如果发现重复的图像/脏区哈希代码,它只向客户端发送哈希代码。
我的问题是这种方法的可行性如何,因为在客户端。 我们需要将哈希码与图像字节数据一起存储在内存中。此应用如何提高内存效率。 或者他们有没有其他方法
。编辑
屏幕共享程序不会发送整个屏幕/区域,time.it 只是通过互联网发送差异/肮脏的reigon.以及如果用户的互联网连接非常差,它会存储每个帧/区域的字节数组以及哈希代码。仅发送哈希码,如果 hascode 与不同的帧/区域字节数组匹配
服务器代码假设
List<uint> hashlist = new List<uint>();
byte[] imagesBytestosend = GetImageBytes();
uint hash = XXHash.XXH32(imagesBytestosend);
if (!hashlist.Contains(hash))
{
hashlist.Add(hash);
SendAllBytesData(imagesBytestosend);
}
else
{
SendOnlyHasCode(hash);
}
客户端代码假设
Dictionary<uint, byte[]> frameData = new Dictionary<uint, byte[]>();
bytes[] imageBytes = null;
if(frameData.ContainsKey(receivedHash))
{
imageBytes=frameData[receivedHash];
}
else
{
imageBytes=receivedBytes;;
frameData.Add(receivedHash, receivedBytes);
//My Question is how this is memory efficient to store frame bytes with his hash code in memory
}
DrawToPictureBox(imageBytes);
如果图像仍处于打开状态,则它仍在客户端的内存中。所以唯一的开销是哈希码,它非常小。如果有的话,它在您描述的场景中是有效的。如果未存储哈希代码,则会再次发送相同的图像(已在内存中),从而浪费带宽并导致相关的性能问题。但是,由于保存了哈希,因此客户端只需从内存中的字节重绘相同的图像。
当然,当您关闭该映像时,与之关联的内存可能会很快释放。因此,如果您在一段时间后打开同一目录,则必须再次发送图像日期以及哈希代码。
听起来您对屏幕共享的工作原理缺乏根本的了解。例如,在Windows中,我们不会检测屏幕缓冲区中的更改。相反,我们依靠Windows将屏幕区域标记为无效。
https://learn.microsoft.com/en-us/windows/desktop/gdi/the-update-region
您可能会注意到,当您启用屏幕共享时,Windows 主题会从 Aero 下降到基本主题。