我们的团队正在Windows上实施VNC查看器(= VNC客户端)。协议(称为RFB)是有状态的,这意味着查看者必须读取1个字节,查看它是什么,然后再读取3或10个字节,解析它们,依此类推。
我们决定使用异步套接字和单个(UI)线程。因此,有两种方法:
1)状态机 - 如果我们在套接字读取时得到一个块,只需记住当前状态并退出。稍后,套接字通知将到达,中断的逻辑将从适当的阶段恢复;
2)内部消息循环 - 一旦我们确定从套接字读取将阻塞,我们进入内部消息循环并在那里旋转,直到最终接收到所有必要的数据。 因此,在块的情况下,UI不会被冻结。
根据经验显示,第二种方法很糟糕,因为当我们处于内部消息循环中时,任何消息都会出现。我不能在这里讲述完整的故事,但它根本不够可靠。崩溃和kludges。
第一种选择似乎是完全可以接受的,但以这种风格编程并不容易。必须记住算法的状态和进一步处理所需的所有局部变量的值。
这很可能使用多个线程,但我们只是认为在这种情况下的问题会更加困难:帧缓冲区访问的同步,多线程问题等等。此外,即使在这个变体中它似乎也需要使用异步套接字。
那么,您认为哪种方式最好?
问题非常普遍。这是通过有状态协议组织异步通信的问题。
编辑1:我们使用C ++和MFC作为UI框架。
答案 0 :(得分:1)
我已经完成了一些并行计算项目,似乎MPI(消息传递接口)可能对您的VNC项目有所帮助。您可能对MPI提供的并行计算能力不太感兴趣,但您可能希望使用简化的类似socket的接口通过网络进行异步通信。
您可以在谷歌找到其他MPI实现和大量使用示例。
答案 1 :(得分:1)
不要打扰CSocket,你最终会转移到CAsyncSocket,因为你得到了额外的控制(中断,关闭等)。我还建议使用单独的线程来管理通信,它增加了复杂性,但保持UI响应应该是首要任务。
答案 2 :(得分:0)
我认为你会发现通过使用一个单独的线程来处理阻塞套接字会大大简化你的设计。
这样做的主要原因是你不需要旋转等待。 UI保持响应,而网络线程阻止它什么都不做,并在有事情要做时返回。您实际上是将大部分开销转移到操作系统。
请记住,RFB不需要大量的状态信息。因为客户端到服务器的消息很短;在发送下一个指针输入之前,没有什么要求你接收帧缓冲区。
我的观点是RFB中的消息可以混合;服务器将按照您的日程安排工作。
现在,Windows提供易于使用的同步API,虽然并不总是最有效,但对于您的目的来说绰绰有余,并且可以轻松获得概念验证。 请查看Windows Synchronization,特别是Critical Sections
仅仅是我的2,我在Windows上实现了vnc服务器和客户端,这些都是我的印象。