Solved

IO::Socket::INET read one byte at a time

Posted on 2006-06-29
6
8,071 Views
Last Modified: 2009-12-16

I am writing a client that will connect over the network to a server. The server will send (upon connect) multiple bytes of binary data, I need the client to log all these bytes of data send by the server. I would also want to handle the input one byte at a time if possible.

I have written a client as below, however, the client doesn't seems to do blocking correctly, it doesn't display anything until the server timeout and disconnect. The question also is how I can get the input one byte at a time. I've tried "$remote->recv($data_read, 1)" but that doesn't seems to work.....

---------------------------------------------------------
#!/usr/bin/perl -w
use IO::Socket;
$remote = IO::Socket::INET->new(
     Proto    => "tcp",
     PeerAddr => "server",
     PeerPort => "1234",
) ;
unless ($remote) { die "cannot connect to remote" }
$remote->autoflush(1);

while ( <$remote> ) { print }

close $remote;
---------------------------------------------------------

Would really like to know how I can get this client to get the binary bytes from the server.

Thanks...
0
Comment
Question by:dillama
  • 3
6 Comments
 
LVL 25

Expert Comment

by:clockwatcher
ID: 17015771
Give this a try:

#!/usr/bin/perl -w
use IO::Socket;
$remote = IO::Socket::INET->new(
     Proto    => "tcp",
     PeerAddr => "server",
     PeerPort => "1234",
) ;
unless ($remote) { die "cannot connect to remote" }
$remote->autoflush(1);

binmode $remote;

my $buffer;
my $numBytesToRead = 1;
my $bytesRead;
my $readcount = 0;

while ($bytesRead = read($remote, $buffer, $numBytesToRead))
{
   $readcount++;
   print $readcount;
   for (my $i = 0; $i < $bytesRead; $i++)
   {
       my $byte = substr($buffer,$i,1);
       print "\t".ord($byte);
       print "\t$byte" if ord($byte) > 26;
       print "\n";
   }
}
print "Read Error: $!\n" unless defined($bytesRead);

close $remote;
0
 

Author Comment

by:dillama
ID: 17025808
That worked great!

Actually, these binary inputs are actually integer type (4 bytes) (feed by a C program). How would I be able to feed it back into my perl program as variables? I know I can manually mess with the input 4 bytes at a time to convert it into a number value (integer), but are there any shortcut (or perl function) that allow me to do this?

Increasing the points to 250 to compensate for extra requirements.
0
 
LVL 25

Accepted Solution

by:
clockwatcher earned 250 total points
ID: 17027702
Use the unpack function.. but to really answer it you need to know whether it's coming in big-ending or little-endian-- see the code below:

#!/usr/bin/perl -w
use IO::Socket;
$remote = IO::Socket::INET->new(
     Proto    => "tcp",
     PeerAddr => "server",
     PeerPort => "1234",
) ;
unless ($remote) { die "cannot connect to remote" }
$remote->autoflush(1);

binmode $remote;

my $buffer;
my $numBytesToRead = 4;
my $bytesRead;
my $readcount = 0;

while ($bytesRead = read($remote, $buffer, $numBytesToRead))
{
   $readcount++;

   if ($numBytesToRead < 4)
   {
      warn "Readcount: $readcount -- what's up with that... only read $numBytesToRead bytes";
   }

   @values = unpack("L*", $buffer);  # long machine dependent byte order-- little-endian on an intel
   # @values = unpack("N*", $buffer);  # big-endian long
   # @values = unpack("V*", $buffer);  # little-endian long
   
   print "$readcount\t$buffer\t";
   $f = 1;
   foreach $intvalue (@values)
   {
      printf "\t"x3 unless $f;
      printf "%x\t$intvalue\n", $intvalue;
      $f = 0;
   }
}
print "Read Error: $!\n" unless defined($bytesRead);

close $remote;
0
 
LVL 25

Expert Comment

by:clockwatcher
ID: 17027710
That warn should have been:

      warn "Readcount: $readcount -- what's up with that... only read $bytesRead bytes";

Personally don't know if it would ever happen.  And if it did it would only happen on a connection close.  The read will block 'til it gets $numBytesToRead bytes.  If the server kills the connection, you might get an undefined return from the read rather than the actual bytes it's read to that point.  Don't know.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

I have been pestered over the years to produce and distribute regular data extracts, and often the request have explicitly requested the data be emailed as an Excel attachement; specifically Excel, as it appears: CSV files confuse (no Red or Green h…
Checking the Alert Log in AWS RDS Oracle can be a pain through their user interface.  I made a script to download the Alert Log, look for errors, and email me the trace files.  In this article I'll describe what I did and share my script.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now