buffer - Ruby packet buffering and splitting -
so, little broad, suppose, i'll try , narrow down as can. have server (with eventmachine) , packets come split, they're buffered. so, tried creating function buffer/un-buffer them. did manage make something, it's not working 'as expected.' quite honest, doubt can call 'barely functional.'
before else, i'll point out packet structure:
- first 4 bytes of packet it's id, or name of packet (
name). - the next 4 bytes length of 'msg' part of packet (
len). - and last 4 bytes before msg part reference field, has various uses (
ref).
note: lenf raw format of len, string, it's not important, think.
the bufferer code
def split(data) if ($packet_buffer != "" && !$packet_buffer.nil?) data = $packet_buffer + data $packet_buffer = "" end last = 0 packets = [] loop if data[last..-1].length < 8 $packet_buffer = data[last..-1] break end name = data[last...last+=4] lenf = data[last...last+4] len = 0 data[last...last+=4].each_byte {|b| len+=b} if !data[last+4..-1].nil? && data[last+4..-1].length < len $packet_buffer = data break end ref = data[last...last+=4] msg = data[last...last+=len] packets << (name << lenf << ref << msg) break if data[last..-1].nil? end packets end tldr
how split buffered , buffer split packets/data (passed eventmachine) in ruby?
update: packets sent on tcp. data comes client made in c, yeah stream of bytes.
i not sure going wrong, method doesn't seem split or buffer packets properly. works fine while receives small amounts of data (which aren't either buffered or split, assume).
sometimes splits packets successfully, if they're buffered, buffering doesn't seem work @ all
i'm sure i'm messing 'logic' part here, can't figure out is. appreciated.
thanks
well here's 1 error jumps out @ me:
len = 0 data[last...last+=4].each_byte {|b| len+=b} you didn't specify format storing length in, if it's little endian integer should len = (len>>8) + (b<<24) instead of adding bytes doing now. current algorithm work fine if len less 256.
there may other logic errors hiding in here. don't use of confusing expressions data[last..-1].nil?; rewrite them simple inequalities involving data.length , last.
if want clean code recommend taking different approach: feed bytes in new function called process_byte 1 @ time. function in charge of keeping track of state information needs (e.g. part of message expecting receive next), assembling bytes complete messages, , passing compelete message on higher-level code. process_byte function unaware of how bytes packetized, right away crush class of bugs program might have.
you use ruby fibers implement process_byte function in nice way allows write code looks synchronous (e.g. len += get_next_byte()) asynchronous.
Comments
Post a Comment