[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