VNC查看器实现

VNC viewer implementation

本文关键字:实现 VNC      更新时间:2023-10-16

我们的团队正在Windows上实现VNC查看器(=VNC客户端)。该协议(称为RFB)是有状态的,这意味着查看器必须读取1个字节,查看它是什么,然后再读取3或10个字节,解析它们,依此类推

我们决定使用异步套接字和单个(UI)线程。因此,有两种方法:

1) 状态机——如果我们在读取套接字时遇到阻塞,只需记住当前状态并退出。稍后,套接字通知将到达,中断的逻辑将从适当阶段恢复;

2) 内部消息循环——一旦我们确定从套接字读取将被阻塞,我们就进入一个内部消息循环并在那里旋转,直到最终接收到所有必要的数据。因此,在块的情况下UI不会被冻结。

经验表明,第二种方法很糟糕,因为当我们处于内部消息循环中时,任何消息都可能出现。我不能在这里讲述全部情况,但它根本不够可靠。崩溃和混乱。

第一种选择似乎是可以接受的,但用这样的风格编程并不容易。必须记住算法的状态以及进一步处理所需的所有局部变量的值。

使用多线程是很可能的,但我们只是认为这种情况下的问题会更加困难:帧缓冲区访问的同步、多线程问题等。此外,即使在这种变体中,似乎也有必要使用异步套接字。

那么,在你看来什么方式是最好的呢?

这个问题很普遍。这就是通过有状态协议组织异步通信的问题。

编辑1:我们使用C++和MFC作为UI框架。

我已经做了一些并行计算项目,MPI(消息传递接口)似乎对您的VNC项目有帮助。您可能对MPI提供的并行计算能力不太感兴趣,但您可能希望使用简化的类似套接字的接口在网络上进行异步通信。

http://www.open-mpi.org/

您可以从谷歌上找到MPI的其他实现和大量使用示例。

不要为CSocket而烦恼,因为你会得到额外的控制(中断、关闭等),所以你最终会转移到CAsyncSocket。我还建议使用一个单独的线程来管理通信,这会增加复杂性,但保持UI响应应该是首要任务。

我想您会发现,通过使用单独的线程来处理阻塞套接字,您的设计将大大简化。

这样做的主要原因是你不需要旋转和等待。UI保持响应,而网络线程在无事可做时会阻塞,在有事可做时又会返回。您实际上将大部分开销转移到了操作系统上。

请记住,RFB不需要大量的状态信息即可工作。因为客户端到服务器的消息很短;在发送下一个指针输入之前,不需要接收帧缓冲区。

我的观点是RFB中的消息可以混合;服务器将按您的时间表工作。

现在,Windows提供了易于使用的同步API,虽然它并不总是最有效的,但对于您的目的来说已经足够了,并且可以轻松地进行概念验证。看看Windows同步,特别是关键部分

就在我的2个实例中,我在windows上实现了vnc服务器和客户端,这是我的印象。