[Gambas-user] gb3 RC1: using structures to replace the loss of Mk$ functions

Benoît Minisini gambas at ...1...
Thu Apr 7 11:05:07 CEST 2011


> On 04/05/2011 03:34 AM, Benoît Minisini wrote:
> >> On 04/05/2011 01:39 AM, Kevin Fishburne wrote:
> >>> Alright, I've transformed all the networking code to the suggested
> >>> solution, and it's so close to working I can smell it. While there is
> >>> more code now, I like it better as it's easier to read (important!).
> >>> 
> >>> Some code:
> >>>      Dim id As Byte
> >>>      Dim type As Byte
> >>>      Dim data As String
> >>>      
> >>>      id = Read #udp As Byte
> >>>      type = Read #udp As Byte
> >>>      If Eof(udp) = False Then data = Read #udp, Lof(udp) - 2
> >>> 
> >>> Using "Lof(udp) - 2" as the length seems to remove bytes from the end
> >>> rather than the beginning. I get an unwanted byte at the beginning as
> >>> well.
> >>> 
> >>> Maybe this is a late April Fools joke about endianness? Other than
> >>> that, the whole app is ready to put pixels on the screen again
> >> 
> >> After checking my code for bugs (none found, knock on wood) and doing
> >> some experimentation, it looks like sending certain data types using the
> >> new method works fine, but other data has an extra byte added in front
> >> of or in-between variables. Any info about what's really happening is
> >> appreciated.
> >> 
> >> Again what I'm trying to do is send an ID (Byte), type (Byte), and a
> >> sequence of arbitrary variables via UDP. When they're received, the ID
> >> and type are read normally as Bytes into variables and the rest of the
> >> data is read into a string and stored in an array for later processing.
> >> The arbitrary variables stored as a string (everything after ID and
> >> type) are later interpreted via the *@() functions and assigned to
> >> variables. To do this I just created a different UDP_Write procedure for
> >> each transaction type so the packets/transactions are properly
> >> assembled. I've attached some code excerpts if anyone desires greater
> >> specificity.
> >> 
> >> In summary of the attachments, the failure basically goes like this:
> >> 
> >> ' Send username and password.
> >> 
> >>     ' Send the transaction.
> >>     udp.Begin
> >>     
> >>       Write #udp, id As Byte
> >>       Write #udp, 50 As Byte
> >>       Write #udp, credentials As String ' credentials =
> >> 
> >> "myusername,mypassword"
> >> 
> >>     udp.Send
> >> 
> >> ' Read the username and password.
> >> 
> >>     id = Read #udp As Byte
> >>     type = Read #udp As Byte
> >>     If Eof(udp) = False Then data = Read #udp, Lof(udp) ' Username and
> >> 
> >> password separated elsewhere, not a problem.
> >> 
> >> data should be "myusername,mypassword" but it actually is
> >> "^Uanon at ...2571...,mypassword". "\x15" prepends the string, strangely. I
> >> think this errant byte also precedes any number of datatypes that are
> >> send separately and later read as a single string. What is this byte,
> >> and how may I get rid of it?
> > 
> > Not strange if you read the doc carefully. :-)
> > 
> > When using "WRITE #Stream, AString As String", the length of the string
> > is always written before the string contents.
> > 
> > To just write the string contents, you must use the second syntax of 
WRITE:
> > 	WRITE #Stream, String, Length
> 
> Writing strings and bytes works fine now, but singles and shorts, not so
> much. Here's an example of what's happening:
> 
> Server - Send ID (0), type (70) and two singles (2279, 1440) as UDP:
> 
>    ' Define target's IP address and port.
>    udp.TargetHost = ip
>    udp.TargetPort = port
> 
>    ' Send the transaction.
>    udp.Begin
>      Write #udp, id As Byte
>      Write #udp, 70 As Byte
>      Write #udp, worldx As Single
>      Write #udp, worldy As Single
>    udp.Send
> 
> Client - Read ID and type into their own variables (id, type) and the
> two singles into a string (data):
> 
>    id = Read #udp As Byte
>    type = Read #udp As Byte
>    If Eof(udp) = False Then data = Read #udp, Lof(udp)
> 
> Client - Display the value of data (double click it in the IDE):
> 
>      E\x0Ep\x00D<?>\x00\x00
> 
>      The "<?>" is actually one character, a question mark in a diamond.
> 
> Client - Print the value of data in the console (?data):
> 
>      E^Np^@D�^@^@
> 
> Client - Print the length of data in the console (?Len[data]):
> 
>      8
> 
> Client - Convert data from a string back into two singles:
> 
>      Single@(Mid$(tsdata, 1, 4))
>          1.029069E-38
> 
>      Single@(Mid$(tsdata, 5, 4))
>          6.466712E-41
> 
> Any idea why 2279 becomes 1.029069E-38 and 1440 becomes 6.466712E-41?
> Sending a short of 1234 is read as "\x04<?>" (double click) or "-11772"
> (Short@[data]). It looks like either the Read function is doing
> something strange with the data when assigning it to a string, or the
> *@() functions aren't working the way they used to. In case anyone
> forgot, I was previously using the Mk*() functions to create a string
> from variables and the *@() functions to convert the string back to the
> original datatypes.

Because sockets are big endian, not little endian as the CPU. I think you have 
to use READ to decode the messages as soon as you receive them. 

If you want to process them later, you can use a Variant[] to store the 
decoded data instead of a String storing the undecoded data.

Regards,

-- 
Benoît Minisini




More information about the User mailing list