Sto usando Ruby 2.0.0p451 (2014-02-24) [x64-mingw32] e mi sono imbattuto in qualcosa che precedentemente funzionava nella versione 1.9.x che non funziona qui. Mi stavo chiedendo se hanno cambiato il comportamento, o se sto facendo qualcosa di sbagliato, o se questo è un bug.
Sto mandando un byte in un socket xFF
e lo ricevo dall'altra parte, ma quando provo a confrontarlo con se stesso (che dovrebbe restituire true) non restituisce l'output atteso.
Esempio, invio la stringa xFFx50x00usernamex00555x00
e lo ricevo bene dall'altra parte, ma quando provo a confrontare il primo byte con se stesso, il condizionale si comporta in modo errato.
Ecco alcuni esempi di codice in modo da poter vedere come sto gestendo i dati (scremato al codice rilevante)
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 Questo unless
la dichiarazione stava funzionando bene. Durante il debug dei dati, i dati restituiti da @receiver.getbyte
è davvero "xFF", ma per qualche motivo il eql?
il confronto restituisce false anziché true causando il ritorno della funzione false. Se rimuovo questo byte dal messaggio e rimuovo il resto del codice chiamando anche il getbyte
il metodo funziona bene.
Anche se cambio il byte in "x55" piuttosto che "xFF" il condizionale unless
la dichiarazione funziona come dovrebbe
Non sono sicuro di cosa stia succedendo. XFF è riservato a qualcosa?
risposte:
0 per risposta № 1Lo sto indovinando buffer
è codificato in binario (ad es. buffer.encoding
è ASCII-8BIT). Ciò significa che ciò sta accadendo:
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`
Invece, dovresti fare semplici confronti numerici:
@receiver.getbyte.getbyte(0) == 255
O ancora meglio, modificare getbyte
per restituire un intero.
Penso che la tua versione 1.9.X funzionasse principalmente per sbaglio, avresti dovuto usare sempre un semplice confronto numerico.
Tieni presente che nel buffer sono presenti byte (come 0xFF e 0x00) che non sono validi nelle stringhe utf-8, pertanto è consigliabile mantenere il buffer in binario. Puoi usare force_encoding
su sezioni del buffer per le parti che sono stringhe utf-8. Potresti voler dare un'occhiata String#unpack
anche.
Nota che sto collegando i documenti specifici di Ruby 2.0.0 in modo che corrispondano alla versione di Ruby attualmente in uso.