Title: RE: [Perl-unix-users] sysread, sockets, reading binary data

Hi Jason,
     how is the weather in the Lone Star. Here are few pieces of code you might find useful.


To the decimal value for a length use the "hex" function.
i.e.
    my $len = 0x00 . 0x0A;
    my $declen = hex $len;




To loop through a scalar named $msg byte by byte use the "substr" function.

my $msg = "abcdefghi";
for (my $i = 0; $i < length $msg; $i++) {
        my $c = substr $msg, $i, 1;
        print $c ."\n";
}



You may also be interested in the "chr" and "ord" functions to convert to and from ASCII/numeric.


If you are running on a Windows version of Perl you may need to set autoflush otherwise writes to the socket will buffer until the buffer is full. This should not be a problem on Unix as it is much more intelligent in its file buffering.

Cheers

Steve



-----Original Message-----
From: Jason Ostrom [mailto:[EMAIL PROTECTED]]
Sent: Tuesday, November 20, 2001 5:21 PM
To: [EMAIL PROTECTED]
Cc: [EMAIL PROTECTED]
Subject: RE: [Perl-unix-users] sysread, sockets, reading binary data


Steve,

Thanks for the response Chief.  Great to see an International community
here.  I'll have to look into using a 'foreach' loop
to push elements into the array.  I don't know yet how that would play
into the accomplishments I made last night.

Here is what I discovered last night:
###############################
# Begin Receive
###############################
$bytes_read = sysread($socket, $buf, 2);
print("\nbytes_read: $bytes_read");

$bytes_to_read = unpack ('H4', $buf);
print ("\nbytes_to_read value :$bytes_to_read\n");

$bytes_read = sysread($socket, $jason, 10);
$messagercv = unpack('H20', $jason);

print ("\nbytes_read: $bytes_read");
print ("\nprinting messagercv: $messagercv\n");
print ("\n Done receiving\n");
###############################
# End Receive
###############################

The server always sends the first two bytes of data with the length in
bytes of the message that follows.  I am receiving 000A, so 10 bytes
of data.

The first thing I need to do is decode this chunk of two bytes, and
unpack it so I get the numeric "10".  Right now I have to hardcode
that 10 in my sysread because I can't get that 10 out of "000A".

Then I need to use the 10 in the next sysread I believe to read the
actual message.  What I am
attempting to do is read the entire 10 bytes into a data structure,
and also read or somehow capture each individual bytes within each
message/data structure that is received so that each individual byte
can be decoded.  I'm getting closer but still not there yet.

I'll play with it more and with what you said, and let you know what
I find.  But if you see anything that jumps out at you, please let me
know.  Steve or anyone.

Thanks once again for your response, and all the best.

-Jason Ostrom
Irving, TX USA


Steve Aaron> Jason,
Steve Aaron>      what about something like.

Steve Aaron> my @bytearray;
Steve Aaron> push @bytearray, unpack "C*", $bufrcv;

Steve Aaron> foreach my $byte (@bytearray) {
Steve Aaron>         ...
Steve Aaron> }


Steve Aaron> Steve Aaron







Jason Ostrom> Hello guys and girls,

Jason Ostrom> I am writing a TCP client program that connects to a server, sends
Jason Ostrom> binary data, and should receive a message back.  The problem I have am
Jason Ostrom> having
Jason Ostrom> is on the receiving end.  I was wondering if any of you have
Jason Ostrom> implemented something like this and may be able to help.

Jason Ostrom> I want the
Jason Ostrom> program to be able to read the socket and, byte by byte, insert data
Jason Ostrom> from the TCP stream into data structure, such as an array, so that
Jason Ostrom> each byte may be referenced later.

Jason Ostrom> Here is the message construction:
Jason Ostrom> ################################################
Jason Ostrom> $Len1 = 0x00;
Jason Ostrom> $Len2 = 0x0A;
Jason Ostrom> $SVCA = 0x96;
Jason Ostrom> $DVCA = 0xDF;
Jason Ostrom> $CTRL = 0x40;
Jason Ostrom> $STAT = 0x00;
Jason Ostrom> $FUNCID = 0x83;
Jason Ostrom> $ACCESS = 0x04;
Jason Ostrom> $RGB1 = 0x00;
Jason Ostrom> $RGB2 = 0x00;
Jason Ostrom> $RGB3 = 0x00;
Jason Ostrom> $RGB4 = 0x0A;
Jason Ostrom> #################################################

Jason Ostrom> # Message construction
Jason Ostrom> $bytestring = pack('C*', $Len1, $Len2, $SVCA, $DVCA, $CTRL, $STAT, $FUNCID,
Jason Ostrom> $ACCESS, $RGB1, $RGB2, $RGB3, $RGB4);

Jason Ostrom> print ("Begin now to send message to socket after $waittime seconds\n");
Jason Ostrom> sleep $waittime;
Jason Ostrom> $len = length($bytestring);

Jason Ostrom> #######
Jason Ostrom> # Here is the routine that sends to the socket...Needs work
Jason Ostrom> #######
Jason Ostrom> $offset = 0;
Jason Ostrom> $bytes_to_write = $len - $offset;
Jason Ostrom> $bytes_written  = 0;
Jason Ostrom> while ($bytes_to_write) {
Jason Ostrom>         $bytes_written = syswrite ($socket, $bytestring, $bytes_to_write,
Jason Ostrom> $offset);
Jason Ostrom>         $offset         += $bytes_written;
Jason Ostrom>         $bytes_to_write -= $bytes_written;
Jason Ostrom>         }

Jason Ostrom> #######
Jason Ostrom> # Receiving section
Jason Ostrom> #################

Jason Ostrom> $offset = 0;
Jason Ostrom> $bytes_to_read = length(<$socket>);
Jason Ostrom> while ($bytes_to_read) {
Jason Ostrom>         $bytes_read = sysread ($socket, $bufrcv, $bytes_to_read, $offset);
Jason Ostrom>         $bytes_to_read -= $bytes_read;
Jason Ostrom>         $offset += $bytes_read;

Jason Ostrom> }



Jason Ostrom> Now I can see with TCPDUMP on this Red Hat 7.2 machine that the server
Jason Ostrom> is sending back the message.  I just need to be able to read the
Jason Ostrom> message into a data structure, a byte at a time.

Jason Ostrom> Any help very much appreciated.
Jason Ostrom> -jason

Reply via email to