我正在使用ruby 2.0.0p451(2014-02-24)[x64-mingw32],我发现以前在1.9.x版本中工作的东西在这里不起作用。我想知道他们是否改变了行为,或者我做错了什么,或者这是一个错误。
我在套接字\xFF
下发送一个字节,然后在另一端收到它,但是当我尝试将它与自身进行比较时(应该返回true),它不会返回预期的输出。
示例,我发送字符串\xFF\x50\x00username\x00555\x00
并且我在另一端接收它很好,但是当我尝试将第一个字节与它自身进行比较时,条件行为错误。
以下是一些代码示例,以便您了解我如何处理数据(浏览相关代码)
class PacketReceiver
def setpacket( buffer ); @buffer = buffer; end
def getbyte
byte = @buffer[0..0]
@buffer = @buffer[1..-1]
byte
end
end
def parsepacket(packet)
#@receiver = PacketReceiver.new #defined elsewhere in code
@receiver.setpacket packet
return false unless @reciever.getbyte.eql? "\xFF" #the bugged line
#Everything works beyond this point
packet_id = @reciever.getbyte
case packet_id
when "\x50"
return sid_requesting_config
when "\x51"
sid_requesting_data_response
when "\x52"
sid_keep_alive_response
else
puts "failed"
return false
end
return true
end
在1.9.X这unless
声明工作正常。调试数据时,@receiver.getbyte
返回的数据确实是" \ xFF"但由于某种原因,eql?
比较返回false而不是true,导致函数返回false。如果我从消息中删除此字节并删除检查其余代码也调用getbyte
方法正常。
此外,如果我将字节更改为" \ x55"而不是" \ xFF"条件unless
语句可以正常工作。
我不确定发生了什么。 \ xFF是为某些东西保留的吗?
答案 0 :(得分:0)
我猜测buffer
是二进制编码的(即buffer.encoding
是ASCII-8BIT)。这意味着发生了这种情况:
c = @receiver.getbyte # c also has binary encoding
ff = "\xff" # ff is probably UTF-8
c.eql? ff # comparing strings in different encodings gives you `false`
相反,您应该进行简单的数字比较:
@receiver.getbyte.getbyte(0) == 255
甚至更好,修改getbyte
以返回整数。
我认为您的1.9.X版本大多是偶然的,您应该一直使用简单的数字比较。
请记住,缓冲区中的字节(例如0xFF和0x00)在UTF-8字符串中无效,因此您应该将缓冲区保留为二进制。您可以在缓冲区的片上使用force_encoding
作为UTF-8字符串的部分。您可能也想查看String#unpack
。
请注意,我链接到Ruby 2.0.0特定文档以匹配您当前使用的Ruby版本。