Sending packets over TCP server

I'm making a TCP server in Ruby, and I still haven't figured out how I
can send packets the way it should be sent. I know how to receive
packets and such though...

For example, one of the packets I need to send looks like this:

Packet ID: 0x00
Purpose: Server Identification: Response to a joining player. The user
type indicates whether a player is an operator (0x64) or not (0x00.)
Current protocol version is 0x07.

Fields:
Packet ID Byte
Protocol Version Byte
Server name String
Server MOTD String
User Type Byte

The code I'm using for the server looks like this:

inform "Starting server"
server = TCPServer.new('127.0.0.1', config['port'])

···

--------------------
while true #Runs all the time, or until user chooses to quit.
  Thread.start(server.accept) do |client|
        data = client.recv(1024)
    data = data.split(" ")
    inform "Recieved Player identification from #{data[0]}"
    client.write "#{config['name']} #{config['motd']}"
    sleep 60
  end
end
--------------------

While it outputs "<Thu Jul 15 18:16:18 +0200 2010> Recieved Player
identification from "(name)"

The client side says that it's been disconnected.

I believe it's because I'm sending data wrong. May someone correct me or
give me pointers?
--
Posted via http://www.ruby-forum.com/.

Zsdfhdfgasdf Gsfgsdgsdgsd wrote:

I'm making a TCP server in Ruby, and I still haven't figured out how I
can send packets the way it should be sent. I know how to receive
packets and such though...

For example, one of the packets I need to send looks like this:

Packet ID: 0x00
Purpose: Server Identification: Response to a joining player. The user
type indicates whether a player is an operator (0x64) or not (0x00.)
Current protocol version is 0x07.

Fields:
Packet ID Byte
Protocol Version Byte
Server name String
Server MOTD String
User Type Byte

You need more detail than that. Is a string of a fixed size, or
terminated by a null, or prefixed by a length byte, or something else?

You can send raw data just by sticking the bytes a string, like this:

  client.write "\x00\x07foobar\x00baz\x07"

For building such strings, Array#pack and String#unpack are going to be
what you're looking for.

[0,7,"foobar","baz",100].pack("CCZ*Z*C")

=> "\000\afoobar\000baz\000d"

···

--
Posted via http://www.ruby-forum.com/\.

Brian wrote:

  client.write "\x00\x07foobar\x00baz\x07"

I didn't know that we could just "escape" characters like that to make
it a byte.

Thanks for that information
(Gawd, I'm so dumb. Why is it so hard to find this stuff?)

···

--
Posted via http://www.ruby-forum.com/\.

Also, if a string DOES contain bytes, it won't show.

···

----------
a = "\x07"
puts "Returns: '#{a}'"
-------------

Returns: ''

-----------------------

How would I manipulate it?
--
Posted via http://www.ruby-forum.com/.

Zsdfhdfgasdf Gsfgsdgsdgsd wrote:

I didn't know that we could just "escape" characters like that to make
it a byte.

http://ruby-doc.org/docs/ProgrammingRuby/

Navigate to chapter "The Ruby Language" in top-left box. Scroll down to
the section headed "Strings", and see the inset box "Substitutions in
double-quoted strings"

(Gawd, I'm so dumb. Why is it so hard to find this stuff?)

The hard part is finding it the first time. It's easy to find it again
:slight_smile:

Regards,

Brian.

···

--
Posted via http://www.ruby-forum.com/\.

Zsdfhdfgasdf Gsfgsdgsdgsd wrote:

Also, if a string DOES contain bytes, it won't show.

----------
a = "\x07"
puts "Returns: '#{a}'"

a = "\x07\x00\x41\x42\x43\xff"
puts "Returns: #{a.inspect}"
puts "Returns: #{a.unpack("H*").first}"

How would I manipulate it?

Just as a String:

a.length
a[1,3] # slice from pos 1 for 3 bytes
.. etc

But if you know precisely the format you're expecting, then
String#unpack will allow you to break it up into integers and
substrings.

···

--
Posted via http://www.ruby-forum.com/\.

Amazing! Then again, thank you. I think I finally reached the point
where I can make this server without opening another Google query!

···

--
Posted via http://www.ruby-forum.com/.