Socket read, write when string found

I know exactly what i need to do, but i cant do it properly…

TCPSocket.open(“209.172.49.193”,6115) {|sock|
#send the server my name 01010101010101
sock.print([“f71e2d00c50d00300000000000e0170900000001010101010101000100020017d7c0a8016b0000000000000000”].pack(“H*”))

#when i watch tcp dump, the server will send me “f70108009a3571cf”
#the last 4 bytes of that string i need to send back to the server to
keep connection alive…
while
sock.print([“f7010800#{gets.chomp}”].pack(“H*”))
end
}

i can keep this connection alive by watching tcpdump, and passing the

value to GETS…

i have been at this for weeks now trying to read from the socket then
print to the socket…

i cant do both at the same time…

as soon as i stop reading from the socket the connection is reset…
data=(sock.gets.unpack(“H*”))
if data.to_s.include?(“f7010800”) == true
ping=data.to_s.index(“f7010800”)
sock.print(["#{data.to_s[ping…ping+15]}"].pack(“H*”))

as soon as i stop reading from the socket the connection is reset…
data=(sock.gets.unpack(“H*”))
if data.to_s.include?(“f7010800”) == true
ping=data.to_s.index(“f7010800”)
sock.print(["#{data.to_s[ping…ping+15]}"].pack(“H*”))

That’s not even a complete code snippet - where is the ‘end’ which
balances the ‘if’?

Anyway, when reading from a socket, you can use:

sock.gets – reads up to a newline (0x0a) character
sock.getc – reads one byte (note: integer in 1.8, string in 1.9)
sock.read(n) – reads exactly n bytes (as a string)
sock.readpartial(n) – reads at least 1 and up to n bytes, depending on
what’s available in the buffer at that time
if select([sock],nil,nil,10) … end – checks whether at least 1 byte
is available to read, or times out after 10 seconds

Almost certainly I’d say you want sock.read(n), not sock.gets, because
it doesn’t look like the binary data you’re reading ends with a newline
character.

Also, note that you can embed hex bytes in strings - this might be
easier than pack, at least for short strings.

sock.print “\xf7\x1e\x2d\x00\xc5\x0d…”

HTH,

Brian.

On Thu, Oct 6, 2011 at 9:53 AM, Brian C. [email protected]
wrote:

Almost certainly I’d say you want sock.read(n), not sock.gets, because
it doesn’t look like the binary data you’re reading ends with a newline
character.

I would use #write and #read as default for binary protocols. If the
protocol has some kind of delimiter sequence #gets might actually work
for reading, because you can pass a parameter for the delimiter:

irb(main):001:0> s = StringIO.new(“fooXXbarXX”)
=> #StringIO:0x109a4060
irb(main):002:0> s.gets ‘XX’
=> “fooXX”
irb(main):003:0> s.gets ‘XX’
=> “barXX”
irb(main):004:0> s.gets ‘XX’
=> nil

Kind regards

robert