Robert Klemme
4/24/2007 4:13:00 PM
On 24.04.2007 17:47, Earle Clubb wrote:
> I'm trying to build a packet to send to UDPSocket::send. Send requires
> a string, but I'm not sure of the best way to build this string. The
> packet's structure requires two strings: one beginning at byte 0 and the
> other at byte 64. The packet is 128 bytes long and must contain 0's in
> the bytes that the strings don't use. Here is an example packet:
>
> 54 68 69 73 20 69 73 20 73 74 72 69 6E 67 20 41 This is string A
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 4E 6F 77 20 77 65 20 68 61 76 65 20 73 74 72 69 Now we have stri
> 6E 67 20 42 00 00 00 00 00 00 00 00 00 00 00 00 ng B............
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
>
> I have a solution, but it's not very elegant and I'm looking for a
> better way of doing this. Here's what I have so far:
>
> I tried this first, but ended up with a bunch of 0x30's where the 0x00's
> should be:
>
> dgram = Array.new(128, 0)
> dgram[0] = "This is string A".to_a
> dgram[64] = "Now we have string B".to_a
> UDPSocket.open.send(dgram.to_s, 0, host, port)
>
> dgram.to_s converts all of the 0x00's in the array to 0x30's in the
> string, which is not acceptable.
>
>
> This is what I have right now:
>
> dgram = ""
> 94.times {dgram << 0}
> dgram[0] = "This is string A"
> dgram[64] = "Now we have string B"
> UDPSocket.open.send(dgram, 0, host, port)
>
> Like I said: it works, but I don't really like it. Any ideas for a
> better implementation?
>> %w{foo bar}
=> ["foo", "bar"]
>> %w{foo bar}.pack("a64a64")
=>
"foo\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000bar\000\000\000\000\000\000\0
00\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0
00\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
Or, printed more nicely:
>> %w{foo bar}.pack("a64a64").to_enum(:each_byte).each_slice(16) {|s|
puts s.map {|x| "%02x" % x}.join(" ")}
66 6f 6f 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
62 61 72 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=> nil
Kind regards
robert