简体   繁体   English

如何实现网络协议?

[英]How to implement a network protocol?

Here is a generic question. 这是一个通用的问题。 I'm not in search of the best answer, I'd just like you to express your favourite practices. 我不是在寻找最好的答案,我希望你能表达你最喜欢的做法。

I want to implement a network protocol in Java (but this is a rather general question, I faced the same issues in C++), this is not the first time, as I have done this before. 我想用Java实现一个网络协议(但这是一个相当普遍的问题,我在C ++中面临同样的问题),这不是第一次,正如我之前所做的那样。 But I think I am missing a good way to implement it. 但我认为我错过了实施它的好方法。 In fact usually it's all about exchanging text messages and some byte buffers between hosts, storing the status and wait until the next message comes. 实际上通常都是关于在主机之间交换文本消息和一些字节缓冲区,存储状态并等到下一条消息到来。 The problem is that I usually end up with a bunch of switch and more or less complex if statements that react to different statuses / messages. 问题是我通常最终得到一堆开关,并且或多或少复杂的if语句对不同的状态/消息作出反应。 The whole thing usually gets complicated and hard to mantain. 整件事情通常变得复杂而难以保持。 Not to mention that sometimes what comes out has some "blind spot", I mean statuses of the protocol that have not been covered and that behave in a unpredictable way. 更不用说有时出现的东西有一些“盲点”,我的意思是协议的状态没有被覆盖并且以不可预测的方式表现。 I tried to write down some state machine classes, that take care of checking start and end statuses for each action in more or less smart ways. 我试着写下一些状态机类,负责以或多或少的智能方式检查每个动作的开始和结束状态。 This makes programming the protocol very complicated as I have to write lines and lines of code to cover every possible situation. 这使编程协议变得非常复杂,因为我必须编写行和代码行来覆盖每种可能的情况。 What I'd like is something like a good pattern, or a best practice that is used in programming complex protocols, easy to mantain and to extend and very readable. 我喜欢的是一个好的模式,或者用于编写复杂协议的最佳实践,易于维护和扩展,并且非常易读。

What are your suggestions? 你有什么建议?

Read up on the State design pattern to learn how to avoid lots of switch statements. 阅读状态设计模式,了解如何避免大量的switch语句。


"sometimes what comes out has some "blind spot", I mean statuses of the protocol that have not been covered..." “有时会出现一些”盲点“,我的意思是协议的状态尚未涵盖......”

State can help avoid gaps. 国家可以帮助避免差距。 It can't guarantee a good design, you still have to do that. 它不能保证良好的设计,你仍然必须这样做。

"...as I have to write lines and lines of code to cover every possible situation." “......因为我必须编写代码行和代码行以涵盖所有可能的情况。”

This should not be considered a burden or a problem: You must write lines of code to cover every possible situation. 这不应被视为负担或问题:您必须编写代码行以涵盖所有可能的情况。

State can help because you get to leverage inheritance. State可以提供帮助,因为您可以利用继承。 It can't guarantee a good design, you still have to do that. 它不能保证良好的设计,你仍然必须这样做。

Designing a protocol is usually all about the application space you are working within. 设计协议通常都与您正在使用的应用程序空间有关。 For instance, http is all about handling web pages, graphics, and posts, while FTP is all about transferring files. 例如,http就是处理网页,图形和帖子,而FTP则是关于传输文件。

So in short, to start, you should decide what application space you are in, then define the actions that need to be taken. 简而言之,首先,您应该确定您所处的应用程序空间,然后定义需要采取的操作。 Then finally, before you start designing your actual protocol, you should seriously, seriously hunt for another protocol stack that does what you want to do and avoid implementing a protocol stack altoether. 最后,在你开始设计你的实际协议之前,你应该认真地,认真地寻找另一个做你想做的事情的协议栈,并避免实现协议栈altoether。 Only after you have determined that something else pre-built absolutely won't work for you should you start building your own protocol stack. 只有在您确定预先构建的其他内容绝对不适合您之后,才能开始构建自己的协议栈。

Finite State Machine is what you want 有限状态机就是你想要的

FSM FSM

So you define a whole bunch of states that you can be in as a receiver or sender (idle, connecting_phase1, connecting_phase2, packet expected,...) 因此,您可以定义一大堆状态,您可以将其作为接收方或发送方(空闲,连接_phase1,连接_用于预期的数据包,...)

Then define all the possible events (packet1 arrives, net closes, ...) 然后定义所有可能的事件(packet1到达,net关闭,......)

finally you have a table that says 'when in state x and event n happens do func y and transition to state q' - for every state and event (many will be null or dups) 最后你有一个表,说'当状态为x且事件n发生了func y并转换到状态q'时 - 表示每个状态和事件(很多都是null或dups)

Edit - how to make a FSM (rough sketch) 编辑 - 如何制作FSM(粗略草图)

 struct FSMNode
 {
      int m_nextState;
      void (m_func*);
 }
 FSMNode states[NUMSTATES][NUMEVENTS]=
   { // state 0
      {3, bang}, // event 0
      {2,wiz},
      {1, fertang}
    }
    {
      {1, noop}, // event 0
      {1, noop},
      {3, ole}
     }
     .......
     FSMNode node = states[mystate][event];
     node.m_func(context);
     mystate = node.m_nextState;

I am sure this is full of invalid syntax - but I hope you get the drift 我确信这充满了无效的语法 - 但我希望你得到漂移

In C++ you can use Boost::Spirit library to parse your protocol message easily. 在C ++中,您可以使用Boost :: Spirit库轻松地解析协议消息。 The only "difficulty" is to define the grammar of your message protocol. 唯一的“难点”是定义消息协议的语法。 Take a look at Gnutella source code to see how they solve this problem. 看看Gnutella源代码,看看他们是如何解决这个问题的。 Here http://www9.limewire.com/developer/gnutella_protocol_0.4.pdf is the Gnutella protocol specifications 这里http://www9.limewire.com/developer/gnutella_protocol_0.4.pdf是Gnutella协议规范

Why not use XML as your protocol? 为什么不使用XML作为协议? You can encapsulate and categorize all your pieces of data inside XML nodes 您可以在XML节点内封装和分类所有数据

Can't give you an example myself, but how about looking at how other (competent) people are doing it? 不能自己给你一个例子,但是如何看待其他(有能力的)人们如何做呢?

Like this one? 像这个? http://anonsvn.jboss.org/repos/netty/trunk/src/main/java/org/jboss/netty/handler/codec/http/ http://anonsvn.jboss.org/repos/netty/trunk/src/main/java/org/jboss/netty/handler/codec/http/

PS for that matter, I actually recommend using netty as your network framework and build your protocol on top of it. PS就此而言,我实际上建议使用netty作为您的网络框架并在其上构建您的协议。 It should be very easy, and you'll probably get rid of bunch of headaches... 它应该很容易,你可能会摆脱一堆头痛......

如果您使用的是Java,请考虑查看Apache MINA ,它的文档和示例应该以正确的方式激励您。

Right-click the network connection icon in the System Tray. 右键单击系统托盘中的网络连接图标。 Click Troubleshoot problems. 单击“疑难解答”。 The troubleshooter may find and fix the problem, in this case, you can get quickly started with your business. 问题排查工具可能会找到并解决问题,在这种情况下,您可以快速开始使用您的业务。 If the troubleshooter can't fix the Winsocks problem, then you may get an error looking like: "One or more network protocols are missing on this computer" 如果故障排除程序无法解决Winsocks问题,则可能会出现以下错误:“此计算机上缺少一个或多个网络协议”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM