使用状态机的网络服务器/客户端的通用架构
总之
,我发明了编写了一个简单的协议,我想用它来让客户端与服务器进行通信。 这是典型的(我认为)三阶段布局:
- 连接建立(最终将包括功能协商)
- 实际数据交换 - 数据包愉快地来回传输,由相应的接收器解释,相应地对它们进行操作
- 连接拆除 - 一侧说“不想再这样了”,另一方说“就这样吧”(最终将允许另一方发送一些数据,直到完成,而不是简单地关闭对话)
该框架是一个简单的设置:服务器java.net.ServerSocket.accept() 并启动一个线程来处理客户端传入的连接,这会创建一个 java.net.Socket() 到服务器正在等待的主机/端口。 .InputStream 和 java.io.OutputStream 相互喷出数据,组装传出消息并解析传入消息,到目前为止
,协议的硬编码非常顺利,而数据交换则非常顺利。部分 - 我想要全双工 - 几乎一团糟。
所以,我想,让我们以一种好方法来做这件事,并使用令人惊讶的同名设计模式来设置状态机。 我非常清楚服务器和客户端应该分别处于什么状态,应该发生什么类型的事件才能发生转换,以及当发生转换时应该采取什么操作。 从纸面上看,这看起来不错。 在实践中,我遇到了一些在纸上无法解决的问题。
特别是,状态机的输入......有点不同。 我怎么可能能够同时写入数据、读取数据和检查连接(它可能已关闭或可能已损坏)? 此外,第一阶段和第三阶段应该有计时器,以避免潜在的无限等待答案的时间。
因此,如果有任何帮助弥合理论状态机和代码状态机之间的差距,我将不胜感激。
顺便说一句,我也可以阅读 C/C++/C# - 无需翻译为 Java(这就是我正在使用的)。
All,
so, I inventedmade up a simple protocol that I want to use for a client to talk to a server. It's the typical (I think) three-phase layout:
- Connection Establishment (will eventually include capability negotiation)
- Actual Data Exchange - packets are happily travelling to and fro', get interpreted by the respective receiver which acts on them accordingly
- Connection Teardown - one side says "don't wanna no more', other side says 'so be it' (will eventually allow the other side to send some data until it is done instead of simply closing the conversation)
The framework is a simple setup: The server does java.net.ServerSocket.accept() and starts a thread to handle the incoming connection by a client, which creates a java.net.Socket() to the host/port where the server is waiting. Both sides use the java.io.InputStream and java.io.OutputStream and spew data at each other, assembling outgoing and parsing incoming messages. Fine, so far.
So far, the protocol is hard-coded. Connection Establishment and Teardown are pretty much ok, while the Data Exchange part - which I want to be full-duplex - is pretty much a mess.
So, thinks me, let's do this the good way and set up a state machine using, surprise, the design pattern of the same name. I'm pretty clear about what the states should be for the server and the client, respectively, and what kinds of events should happen for a transition to take place, and what actions should be undertaken when a transition does happen. That looks good - on paper, that is. In practice, I've stubmled over a couple of questions that I can't solve on paper.
In particular, the inputs of the state machine are ... a little diverse. How could I possibly be able to write data, read data and check the connection (it might have closed or may be broken) at the same time? Also, the 1st and 3rd phase should get timers to avoid potentially infinite waiting times for answers.
So, I'd be grateful for any help that bridges my gap between the theory state machine and the code state machine.
BTW, I can read C/C++/C# too - no need to translate to Java (which is what I'm using).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的计算机的状态需要按“连接”存储
每个客户端连接可能处于不同的状态。 因此,如果您有一个对象跟踪您的状态,那么每个连接都会有该对象的一个实例。
我实际上写了一个小库,如果您感兴趣的话,它可以从状态机中抽象出几乎所有内容。 那里还有一些测试代码,可以向您展示如何使用它。 状态机代码
它执行一些您可能会忘记的操作,例如确保状态转换不“有效”实际上是一个错误,而不是可能被错过,并且记录状态转换是免费的。
附注 (任何人)如果你看了它但不喜欢它——请告诉我为什么。 我想让它对任何人都可用。
The state for your machine needs to be stored per "Connection"
Each client connecting might be in a different state. So if you had an object tracking your state, you would have an instance of that object for every connection.
I actually wrote a little library that abstracts out just about everything from the state machine if you're interested. There is some test code in there as well that should show you how to work it. State Machine Code
It does some stuff you might forget, like ensuring that state transitions that are not "valid" are actually an error rather than maybe being missed, and logging state transitions is free.
ps. (Anyone) If you look at it and don't like it--please let me know why. I'd like to make it usable for anyone.