Sending packets over TCP server

  • Thread starter Zsdfhdfgasdf Gsfgsdgsdgsd
  • Start date
Z

Zsdfhdfgasdf Gsfgsdgsdgsd

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?
 
B

Brian Candler

Zsdfhdfgasdf said:
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"
 
Z

Zsdfhdfgasdf Gsfgsdgsdgsd

Brian said:
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?)
 
B

Brian Candler

Zsdfhdfgasdf said:
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.
 
B

Brian Candler

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

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.
 
Z

Zsdfhdfgasdf Gsfgsdgsdgsd

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

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,967
Messages
2,570,148
Members
46,694
Latest member
LetaCadwal

Latest Threads

Top