有人可以更好地解释解码器/编码器吗?

时间:2012-12-20 09:25:56

标签: netty

修订问题:

好的,所以我想把它融入我自己的定制游戏中。我理解Netty服务器和客户端如何连接的过程。我也理解解码器和编码器在理论上是如何工作的。但这是我仍然想要了解的内容。

我的服务器进程:

Server boots up -> Client starts
Client requests connection -> Server accepts
Server instructs client connection is good -> Client continues to the login screen
(Ignoring any type of security protocol)
Client sends username and password over Channel
Server gets username and password checks it in the database or file
Server pushes -> yes or no
if yes Server sends player stats
if no Server creates new player

在那个过程之后,我知道我需要一个世界处理程序,以便每个人都能近乎实时地看到更新。现在我不知道如何为这些东西实现解码器。

我真的希望看到一些例子,并说明如何实施这些例子。 最好是一些指示.... 注意:我不是说为我解决这个问题,而是告诉我如何处理不同的信息。最佳实践和标准请....

1 个答案:

答案 0 :(得分:4)

人们编写自己的编码器/解码器(编解码器),因为Netty没有强加或定义应用程序级协议,因此您可以自由编写自己的协议。您定义的一组编解码器是一种协议,例如,可以是基于String和一些二进制格式之间的任何协议,如Protobuf。 Netty为您提供方便的编解码器(您使用的是示例)。

  
    

我认为这是为了防止流被提前切断?

  

通常,当您发送/接收流时,您需要在固定长度的块(称为帧)上对其进行分解。自互联网诞生以来一直使用的一种流行方法是使用块的长度(通常为4字节int)作为从流中读取的第一个字段。因此,如果第一个int的值是20,那么您知道后面的20个字节是有效负载(数据),第21个字节是另一个长度的第一个字节。这种方法的优点是它允许可变长度的块。但你不仅限于此。例如,如果您计划编写一个使用具有预定义长度(使用填充)的字符串的协议,那么您将编写或甚至更好地使用适合它的Netty当前编解码器。

有一次,我实现了一个带有三个解码器的协议,它们将按此顺序执行:

  1. 接收一个流并将其分解为长度为前缀的帧;
  2. 将每个帧转换为字符串;
  3. 使用Jackson libray将字符串转换为预定义的Java对象。
  4. 编码器只会执行相同的操作,但会向后执行。不幸的是,我丢失了原始代码,但我很快就会重写它。

      
        

    但是,流如何知道流是String还是一系列int或一系列双精度?你怎么说它的区别在于问题?

      

    简短的回答:它不知道。您必须在编解码器中对此信息进行编码。例如,您可以使用操作码作为有效负载中的第一个字段,表示有效负载是字符串,双精度,整数或两者的任意组合。

    基本上,Netty提供了一个流,您可以随意解码。例如,如果您正在读取一系列长整数(8个字节),那么您将编写一个从流中一次读取64个字节的编解码器,因为每个长度代表一个长整数。 Netty提供开箱即用的编解码器,因此您无需每次都重新发明轮子。