使用状态机的网络服务器/客户端的通用体系结构

时间:2008-11-18 21:59:34

标签: networking client-server tcp state-machine

所有

所以,我发明了组成了一个简单的协议,我想用它来让客户端与服务器通信。这是典型的(我认为)三阶段布局:

  • 连接建立(最终将包括能力协商)
  • 实际数据交换 - 数据包正在愉快地往返行进,由相应的接收器解释,相应地对它们起作用
  • 连接拆解 - 一方说“不想再多了”,另一方说“就这样”(最终会让对方发送一些数据,直到完成而不是简单地关闭对话)

框架是一个简单的设置:服务器执行java.net.ServerSocket.accept()并启动一个线程来处理客户端的传入连接,这会创建一个java.net.Socket()到主机/端口服务器在哪里等待。双方使用java.io.InputStream和java.io.OutputStream并相互发送数据,组合传出和解析传入消息。很好,到目前为止。

到目前为止,该协议是硬编码的。连接建立和拆解非常好,而数据交换部分 - 我想要全双工 - 几乎是一团糟。

所以,想想我,让我们这样做的好方法,并设置一个状态机,使用,惊喜,同名的设计模式。我很清楚应该分别为服务器和客户端提供状态,以及发生转换时应该发生什么类型的事件,以及在转换发生时应该采取什么行动。那看起来很好 - 在纸面上,就是这样。在实践中,我已经发现了一些我无法在纸上解决的问题。

特别是,状态机的输入......有点多样化。我怎么能够同时写入数据,读取数据和检查连接(它可能已关闭或可能已损坏)?此外,第1阶段和第3阶段应该有定时器,以避免潜在的无限等待答案。

所以,我很感激任何帮助弥合理论状态机和代码状态机之间的差距。

顺便说一下,我也可以阅读C / C ++ / C# - 不需要翻译成Java(这就是我正在使用的)。

1 个答案:

答案 0 :(得分:0)

您的机器状态需要按“连接”存储

每个客户端连接可能处于不同的状态。因此,如果您有一个跟踪状态的对象,那么每个连接都会有一个该对象的实例。

我实际上写了一个小库,如果你感兴趣的话,可以从状态机中抽象出所有东西。那里还有一些测试代码,可以告诉你如何使用它。 State Machine Code

它会做一些你可能忘记的事情,比如确保非“有效”的状态转换实际上是错误而不是错过,并且记录状态转换是免费的。

PS。 (任何人)如果你看它并且不喜欢它 - 请告诉我原因。我想让任何人都可以使用它。