[Mpls-pm] A problem with reading from a socket

Dan Oelke Dan at oelke.com
Thu Jul 1 11:08:28 CDT 2004


I am having a problem reading from a socket - it seems like it might be 
buffering related, but I can't seem to figure this one out.  Any 
suggestions as to things to check would be appreciated.

The script opens a socket to an industrial camera that spits out a 
series of lines every inspection it makes.  The format of the output is 
such that every block of data starts with a line that has "START" and 
ends with a line that has "END".  My problem is that often I will get 
the "START" line and then I don't get any more data for that 
inspection.  I am using a polling method to check for more data (other 
stuff needs to go on) so I am using select with a 100ms timeout to check 
if the socket is readable.  That select call is never showing that 
socket as being readable - even though there must be data there.  I keep 
checking for data for about 10 seconds (in a loop for 100x) before 
giving up.

I have checked the embedded code in the camera - and it is doing a flush 
on the socket - so the data should be at the monitoring PC.  I have had 
this working just perfectly on my "normal" machine which is Windows2000, 
but I take this script to a PC in the lab, running Windows NT4, and it 
gives me this select/timeout/buffer problem.  This is all using the 
latest cygwin perl, not ActiveState.

Below is the code from the module that does this socket communication 
(with lots of extra debugging print stuff)

Thank you,
Dan




sub new {
  my ($address,$port) = @_;
  my $self = {};
  $self->{STATE}= "startupState";
  $self->{TOOLNAME} = "unknownTool";

  $self->{CAMERASOCKET} = IO::Socket::INET->new(PeerAddr => $address,
                                                PeerPort => $port,
                                                Proto    => "tcp",
                                                Type     => SOCK_STREAM)

  or die "Couldn't connect to $address on port $port - $@\n";

  bless($self);
  return $self;
}

#
# check for data on the socket - will return the number of START/END 
pairs processed.
# currently will return every inspection so result is either 0 or 1 only.
#
sub checkForData {
  my $self = shift;
  $select = new IO::Select;
  my $socket = $self->{CAMERASOCKET};
  $select->add($socket);
  # check for data - wait a max of 100ms
  while (@ready = $select->can_read(0.1)) {
    my $inputLine = <$socket>;
    print "====                     $inputLine";
    switch($self->{STATE}) {
      case "startupState"
        {
          if ($inputLine =~ /^END/) {
            $self->{STATE} = "waitForStart";
            return 0;
          }
          if ($inputLine =~ /^START/) {
            $self->{STATE} = "gather";
            my %LastResults;
            $self->{LASTRESULTS} = \%LastResults;
            print "---------Done in Startup \n";
            return 0;
          }
        }
      case "waitForStart"
        {
          if ($inputLine =~ /^START/) {
            $self->{STATE} = "gather";
            print "---------Wait for Start exit \n";
          }
        }

      case "gather"
        {
          if ($inputLine =~ /END/) {
            $self->{STATE} = "waitForStart";
            print "---------Gather done\n";
            return 1;
          } elsif ($inputLine =~ /=/) {
            my ($name,$values) = split(/=/,$inputLine);
            chomp($name,$values);
            $values =~ s/\r//;
            $self->processResults($name,$values);
          } else {
            $self->{TOOLNAME} = $inputLine;
            chomp $self->{TOOLNAME};
            $self->{TOOLNAME} =~ s/\r//;
            print "---------Got Tool $self->{TOOLNAME}\n";
          }
        }
      }
   }
}



More information about the Mpls-pm mailing list