Sending strings

7 views
Skip to first unread message

Mizipzor

unread,
Mar 23, 2007, 9:41:15 AM3/23/07
to pyraknet mailing list
This must be the first code project Ive ever stumbled upon that didnt
already have a couple of thousand users. Yay for the underground
feeling, hehe. On a more serios note, kudos for making the pybindings
for raknet. :)

Now, I looked up the (only) example to see how to use pyraknet. So
this is the way you send data to another peer:

data = struct.pack('B', PacketTypes.ID_USER_PACKET_ENUM)
self.net.send(data, len(data), ... )

Ive never used the struct module before but after some googling I
found that it packages stuffs into structs (ok, maybe I could have
guessed that) and the 'B' stands for binary packaging. The other
parameter is an int, or actually its an enum stating what kind of
package this is, so the other peer knows.

With that settled, its easy to send stuff to the other peer. But youre
limited to what raknet got built in, what if you want to send a
message? Like a motd upon connection to the server. I fond that doing
like the following I could send complete strings:

data = "abc"
self.net.send(data, len(data), ... )

But now, the other peer would think that the package-code is 97, "a".
And I (of course) cant just put the code in there:

data = "71abc"

Now the other peer thinks the packte-code is 55, a "7". Hmm... Im
always making my posts to these to long, yapping away for ages about
what doesnt work. :P Anyone can tell me how to send an ordinary string
to the other peer?

Mizipzor

unread,
Mar 23, 2007, 1:33:08 PM3/23/07
to pyraknet mailing list
I think Ive come up with a solution now, but I wouldnt say its pretty.

Reading here, http://docs.python.org/lib/module-struct.html, you see
that struct.pack can pack strings with the format 'length-of-
string'+s. What I do is I put the raknet-packagetype-flag encoded as a
char first, like in the example, concatenate the message after it,
pack it and send:

def send(self, message, address):
""" send a text message to an address """
# insert the packet flag before the message
message = chr(PacketTypes.ID_USER_PACKET_ENUM)+message
# this how we are packing the data, (length-of-string)+'s'
format = str(len(message)+1)+"s"
data = struct.pack(format, message)
self.net.send(data, len(data), PacketPriority.MEDIUM_PRIORITY,
PacketReliability.RELIABLE, 0, address)

Then upon receival, if the first character, coded back into an int, is
the same as the ID_USER_PACKET_ENUM, I use a decode function to make a
string of the packed chars:

def handlePacket(self, packet):
""" handle a packet send from one of the clients """
p = ord(packet.data[0])
(...)
elif p == PacketTypes.ID_USER_PACKET_ENUM:
print "got '",self.decodeMessage(packet),"' from
'",self.net.get_address_string(packet.address),"'

And heres the decode function:

def decodeMessage(self, packet):
""" returns the a string that is the message from a pyraknet-
packet """
ret = ""
for c in packet.data[1:]: #cut pyraknet flag
ret += chr(ord(c))
return ret[:-1] #cut null terminator

Now I just need to come up with something cool to try it out with!
Hehe. Just tell me if you wanna see the full source.

Conrado PLG

unread,
Mar 23, 2007, 1:53:10 PM3/23/07
to pyra...@googlegroups.com
On 3/23/07, Mizipzor <mizi...@gmail.com> wrote:
>
> I think Ive come up with a solution now, but I wouldnt say its pretty.
>
> Reading here, http://docs.python.org/lib/module-struct.html, you see
> that struct.pack can pack strings with the format 'length-of-
> string'+s. What I do is I put the raknet-packagetype-flag encoded as a
> char first, like in the example, concatenate the message after it,
> pack it and send:

Actually, you can do this way which I think it's simpler...

def send(self, message, address):
message = struct.pack('B', PacketTypes.ID_USER_PACKET_ENUM) + message
self.net.send(messsage, len(message), PacketPriority.MEDIUM_PRIORITY,
PacketReliability.RELIABLE, 0, address)

def handlePacket(self, packet):


p = ord(packet.data[0])
(...)
elif p == PacketTypes.ID_USER_PACKET_ENUM:

print "got '", packet.data[1:],"' from
'",self.net.get_address_string(packet.address),"'

Mizipzor

unread,
Mar 23, 2007, 2:49:08 PM3/23/07
to pyraknet mailing list
Hmm... maybe youre right, but in that case this should also work,
which is even simpler:

message = chr(PacketTypes.ID_USER_PACKET_ENUM) + message

Whats the reason were packing that single byte anyway? Why not
typecast it like this?

On Mar 23, 6:53 pm, "Conrado PLG" <conrado...@gmail.com> wrote:


> On 3/23/07, Mizipzor <mizip...@gmail.com> wrote:
>
>
>
> > I think Ive come up with a solution now, but I wouldnt say its pretty.
>

> > Reading here,http://docs.python.org/lib/module-struct.html, you see

Conrado PLG

unread,
Mar 23, 2007, 7:05:51 PM3/23/07
to pyra...@googlegroups.com
On 3/23/07, Mizipzor <mizi...@gmail.com> wrote:
>
> Hmm... maybe youre right, but in that case this should also work,
> which is even simpler:
>
> message = chr(PacketTypes.ID_USER_PACKET_ENUM) + message
>
> Whats the reason were packing that single byte anyway? Why not
> typecast it like this?

Indeed... It's the same, unless I'm missing something.

Gerald Kaszuba

unread,
Mar 25, 2007, 8:21:51 PM3/25/07
to pyraknet mailing list
Hi

> message = chr(PacketTypes.ID_USER_PACKET_ENUM) + message

That's probably the easiest way to send a string as long as it is the
only data in the packet.

If you want to send more data in the packet, for example two strings,
you need to do make sure the receiving end knows the length of the
strings. The way I do it is to send a byte of the length of the string
(as a byte) before the string and have the string right after it.
Here's some code to demonstrate:

>>> mystr1 = "hello"
>>> mystr2 = "my player name"
>>> message = chr(100)
>>> message += chr(len(mystr1)) + mystr1
>>> message += chr(len(mystr2)) + mystr2
>>> message
'd\x05hello\x0emy player name'

Also, the reason for using struct.pack is to make sure your numbers
are in the correct endian format by using the "!" character. i.e.:
>>> import struct
>>> struct.pack('!i', 500)
'\x00\x00\x01\xf4'
>>> struct.pack('i', 500)
'\xf4\x01\x00\x00'

Gerald

Reply all
Reply to author
Forward
0 new messages