Sending packets over TCP server

Discussion in 'Ruby' started by Zsdfhdfgasdf Gsfgsdgsdgsd, Jul 15, 2010.

  1. 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, Jul 15, 2010
    #1
    1. Advertising

  2. 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 Candler, Jul 15, 2010
    #2
    1. Advertising

  3. 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/.
     
    Zsdfhdfgasdf Gsfgsdgsdgsd, Jul 15, 2010
    #3
  4. 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, Jul 15, 2010
    #4
  5. 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
    :)

    Regards,

    Brian.
    --
    Posted via http://www.ruby-forum.com/.
     
    Brian Candler, Jul 15, 2010
    #5
  6. 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/.
     
    Brian Candler, Jul 15, 2010
    #6
  7. 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/.
     
    Zsdfhdfgasdf Gsfgsdgsdgsd, Jul 15, 2010
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. antoine
    Replies:
    3
    Views:
    4,834
    antoine
    Dec 7, 2005
  2. Chris
    Replies:
    2
    Views:
    299
    Howard
    May 14, 2004
  3. Thomas Jollans
    Replies:
    0
    Views:
    381
    Thomas Jollans
    Aug 2, 2007
  4. Gary Herron
    Replies:
    1
    Views:
    448
    Azazello
    Aug 2, 2007
  5. Thomas Johnson

    Timestamps for TCP packets?

    Thomas Johnson, Oct 2, 2009, in forum: Python
    Replies:
    2
    Views:
    862
    Grant Edwards
    Oct 2, 2009
Loading...

Share This Page