2013-07-13 57 views
3

所以我在GitHub上分配了这个gem,认为我可以修复和更新一些与Rails项目相关的问题。我基本上得到这个输出:Ruby Gem随机返回编码错误

irb(main):020:0> query = Query::simpleQuery('xx.xxx.xxx.xx', 25565) 
=> [false, #<Encoding::CompatibilityError: incompatible character encodings: UTF-8 and ASCII-8BIT>] 

irb(main):021:0> query = Query::simpleQuery('xx.xxx.xxx.xx', 25565) 
=> {:motd=>"Craftnet", :gametype=>"SMP", :map=>"world", :numplayers=>"0", :maxplayers=>"48"} 

第一个响应是编码错误的例子,第二个是需要的输出(IP取出)。基本上这是查询一个Minecraft服务器的信息。

我尝试使用

Encoding.default_external = Encoding::UTF_8 
Encoding.default_internal = Encoding::UTF_8 

但是,这只是给了同样的答复,随机随地吐痰编码错误,而不是。

下面是相关GitHub库的所有代码:RubyMinecraft

任何帮助将不胜感激。

回答

2

Query类有this line

@key = Array(key).pack('N') 

这产生与ASCII-8BIT的相关联的编码字符串(即它是一个二进制串)。

后来@keythis line被使用:

query = @sock.send("\xFE\xFD\x00\x01\x02\x03\x04" + @key, 0) 

在Ruby 2.0字符串文字的默认编码为UTF-8,所以这是组合UTF-8字符串,二进制一。

当Ruby尝试这样做时,它首先检查二进制字符串是否只包含7位值(即,所有字节小于或等于127,顶部字节为0),如果它执行它认为它与UTF-8兼容,因此将它们结合起来而不会有进一步的问题。如果不是,(即如果它包含大于127的字节),则两个字符串不兼容,并且引发Encoding::CompatibilityError

是否引发错误取决于@key的内容,它是从服务器的响应中初始化的。有时这个值只包含7位值,所以不会产生错误,在其他时候有一个高位设置的字节,所以会产生一个错误。这就是为什么这些错误似乎是“随机的”。

要修复它,您可以指定将两个字符串组合在一行中的字符串文字视为二进制文件。最简单的方法是使用force_encoding这样的:

query = @sock.send("\xFE\xFD\x00\x01\x02\x03\x04".force_encoding(Encoding::ASCII_8BIT) + @key, 0) 
+0

太感谢你了,不但没这进一步红宝石我的知识,同时也固定我的问题。 – Tylerjd