Ich verwende Ruby 2.0.0p451 (2014-02-24) [x64-mingw32] und ich bin auf etwas gestoßen, das zuvor in der 1.9.x-Version funktioniert hat und hier nicht funktioniert. Ich habe mich gefragt, ob sie das Verhalten geändert haben, ob ich etwas falsch mache oder ob dies ein Fehler ist.
Ich sende ein Byte durch eine Socket xFF
und ich empfange es am anderen Ende, aber wenn ich versuche, es mit sich selbst zu vergleichen (was wahr sein sollte), wird die erwartete Ausgabe nicht zurückgegeben.
Beispiel, ich schicke die Zeichenfolge xFFx50x00usernamex00555x00
und ich erhalte es gut am anderen Ende, aber wenn ich versuche, das erste Byte mit sich selbst zu vergleichen, verhält sich die Bedingung falsch.
Hier einige Codebeispiele, damit Sie sehen können, wie ich mit den Daten umgehe (mit relevantem Code).
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
In 1.9.X This unless
Aussage funktionierte gut. Beim Debuggen der Daten werden die Daten von zurückgegeben @receiver.getbyte
ist zwar "xFF", aber aus irgendeinem Grund das eql?
Der Vergleich gibt "false" statt "true" zurück, sodass die Funktion "false" zurückgibt. Wenn ich dieses Byte aus der Nachricht entferne und die Überprüfung entferne, wird auch der Rest des Codes aufgerufen getbyte
Methode funktioniert gut.
Auch wenn ich das Byte in "x55" und nicht in "xFF" die Bedingung verändere unless
Aussage funktioniert wie es sollte.
Ich bin nicht sicher, was los ist. Ist xFF für etwas reserviert?
Antworten:
0 für die Antwort № 1Ich vermute das buffer
ist binär codiert (d. h. buffer.encoding
ist ASCII-8BIT). Das bedeutet, dass dies geschieht:
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`
Stattdessen sollten Sie einfache numerische Vergleiche durchführen:
@receiver.getbyte.getbyte(0) == 255
Oder noch besser, modifizieren getbyte
eine ganze Zahl zurückgeben
Ich denke, Ihre 1.9.X-Version funktionierte meistens aus Versehen, Sie hätten schon immer einen einfachen numerischen Vergleich verwenden sollen.
Denken Sie daran, dass sich in Ihrem Puffer Bytes (wie 0xFF und 0x00) befinden, die in utf-8-Zeichenfolgen nicht gültig sind. Sie können verwenden force_encoding
auf Scheiben des Puffers für die Teile, die utf-8-Zeichenketten sind. Vielleicht möchten Sie es sich ansehen String#unpack
auch.
Beachten Sie, dass ich auf die Ruby 2.0.0-spezifischen Dokumente verlinke, die der aktuell verwendeten Ruby-Version entsprechen.