[Mpls-pm] Perl Socket programming problem with Windows
Paul.Krcma@wellsfargo.com
Paul.Krcma at wellsfargo.com
Wed Aug 17 11:18:27 PDT 2005
Hello,
I'm writing a TCP Server program that polls waits for socket connections
on a specified port. The connection will be coming from a "black box"
test harness written in C#.Net. The connection hand-shake design is as
follow:
Black Box requests to connect to the Server
Server responds back with a "Challenge" with a hardcode string
"1001|1000"
The Black Box reads the Challenge, then returns another request as
"1001|1100"
The Server will then processes the second request.
On my Server end, I can start the server and wait for connections. When
the Client makes a request to the Server, the Server accepts the
connections, but I can't read the data being sent. When I attempt to
read the data stream on the Server, it wait about 5 seconds, then the
Client hangs. I'm using IO::Socket and IO::Select, and I've tried read,
recv, <>, Open(filehandle), all attempts result with the same error.
Here's my Server code:
use IO::Socket qw(:DEFAULT :crlf);
#use IO::Socket;
#use IO::Socket::INET;
use IO::Handle;
use IO::Select;
use POSIX;
use Socket;
use Fcntl;
use Tie::RefHash;
use Net::Socket::NonBlock;
local($/) = LF;
# Setup global variables
$ViewServer = "M:\\paul.krcma_csm_test\\PaulsTest\\release1";
#$ServerName = 'EPWS3001';
$ServerName = 'RCSLMN10L3CNMW6';
$port_num = '8003';
$ReqId = "1000";
$client = "";
# Create socket object
$server = IO::Socket::INET->new('LocalPort' => $port_num,
'Proto' => 'tcp',
'Type' => SOCK_STREAM,
'Block' => 0,
'Listen' => 16,
'Reuse' => 1)
or die "Can't create socket ($!)\n";
%inbuffer = ();
%outbuffer = ();
%ready = ();
tie %ready, 'Tie::RefHash';
#nonblock($server);
# Create a new IO::Socket Object
$select = IO::Select->new;
$select->add($server);
#my $select->add($socket); # Add a Listener to the IO::Socket
object
print "Server listening\n";
# Wait for incoming requests, and open new sockets when needed
while (1) {
$client;
$rv;
$data;
$sn;
foreach $client ($select->can_read()) {
print "Creating TCPSocketListener\n";
print "Checking for client = server\n";
if($client == $server) {
#my $new;
# Level 1 If
# Create a new socket and add the handles to the Select object
$client = $server->accept();
$select->add($client);
$client->autoflush(1);
$client->blocking(false);
$ClientName = gethostbyaddr($client->peeraddr, AF_INET);
#print "data is $rv{$client}\n";
#print "New Socket opened\n";
#print "Generating RequestId and sending Challenge to back to
Core\n";
$buffer = '';
$rv = recv($client, $buffer, 1024,0); ########### This
line causes the Client to hang ######################
&Generate_ReqId($ReqId);
#print "Req ID = $ReqId\n";
print "Reading data\n";
#$sn = $client->send($ReqId);
#while(<$client>) {
# chop $_;
# $data = $_;
#}
print "Data received is $data\n";
#$SendPack = $ReqId."|1000\015\012";
#$sn = $client->send($SendPack);
#$client "$ReqId|1000";
#print "Inside level 1 if\n";
#print "Authorizing user\n";
#print $new "$ReqId|0|";
print "Leaving the client-server loop\n";
}
else {
# Fork the incoming connection from the parent
print "A separate connection\n";
print "Packet is $packet\n";
#&process_connection;
$data = '';
$rv = $client->recv($data, POSIX::BUFSIZ, 0);
unless (defined($rv) && length $data) {
# Client disconnected so do some cleanup
print "Going to delete the buffers\n";
print $client "OK";
delete $inbuffer{$client};
delete $outbuffer{$client};
delete $ready{$client};
$select->remove($client);
close $client;
next;
}
$inbuffer{$client} .= $data;
#print " Existing Connection\n";
#print "Received Authentication string from Core\n";
#print $rv{$client};
#print "Sending Authentication approval back to Core\n";
#print $client "$ReqId|0|";
#&process_connection;
while ($inbuffer{$client} =~ s/(.*\n)//) {
print "building array of requests\n";
push( @{$ready{$client}}, $1 );
}
}
print "Outside If\n";
}
# Any complete requests to process ?
foreach $client (keys %ready) {
print "Handling a request\n";
handle($client);
}
# Buffers to flush ?
foreach $client ($select->can_write(1)) {
print "Flushing the buffers\n";
#next unless exists $outbuffer{$client};
print "Sending information to the outbuffer\n";
$rv = $client->send($outbuffer{$client}, 0);
unless (defined $rv) {
warn "I can't write\n";
next;
}
print "Reading the length of the outbuffer\n";
if ($rv == length $outbuffer{$client} ||
$! == POSIX::EWOULDBLOCK) {
print "Doing some stuff with the outbuffer\n";
substr($outbuffer{$client}, 0 , $rv) = '';
delete $outbuffer{$client} unless length $outbuffer{$client};
}
else {
print "Cleaning up the flush buffers\n";
delete $inbuffer{$client};
delete $outbuffer{$client};
delete $read{$client};
select->remove($client);
close($client);
next;
}
print "Leaving Flush Buffers\n";
#$select->remove($client);
#close $client;
}
print "Leaving the Listener\n";
#close $client or die "Can't close ($!)\n";
} die "Can't accept socket ($!)\n";
sub Generate_ReqId($Rid) {
$ReqId++;
return $ReqId;
}
sub handle {
my $client = shift;
print "Inside the Handle sub $client\n";
my $request;
foreach $request (@{$ready{$client}}) {
print "Inside the request for loop $request\n";
# put the text of reply into the $outbuffer{$client}
$outbuffer{$client} .= $request;
$packet = $outbuffer{$client};
print "Packet is $outbuffer{$client}\n";
}
delete $ready{$client};
}
sub process_connection {
print "Inside process_connection\n";
#print $client "$.: $_";
$CoreReqId = "";
$ReqType = "";
$CNNum = "";
$ProjId = "";
$CdPack = "";
$CdPackLoc = "";
#my $ClientName = gethostbyaddr($socket->peeraddr, AF_INET);
#my $port = $socket->peerport;
#print "[$ClientName $port]\n";
# Once a client has been accepted, print out the client information
and the packet it sent
while (<$client>) {
$packetname = $_;
print "Packet is $_\n";
#print "[$ClientName $port] $_";
#print $client "$.: $_";
# Parse the packet
# NOTE: Don't chop the packet. The return character needs to remain
imbedded in
# the packet to return back to the client
($CoreRegId,$ReqType,$CNNum,$ProjId,$CdPack,$CdPackLoc) =
split(/\|/,$packetname);
print "$CoreReqId, $ReqType $CNNum $ProjId $CdPack $CdPackLoc\n";
# Chop the last entry of the split string and join the CdPackLoc
with CdPack
chop $CdPackLoc;
$NewElement = $CdPackLoc.$CdPack;
#$EndTime = `echo %time%`;
#print "End Time = $EndTime\n";
$select->remove($client);
$client->close;
}
}
The programmer for the Black Box side assures me that he is not putting
any special end-of-line characters in his output string. I'm at a total
loss for what is going on here. Any help would be appreciated.
Thanks,
Paul Krcma
CMI Client/Server (EISS)
612-316-3712
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.pm.org/pipermail/mpls-pm/attachments/20050817/ee9f3bc5/attachment-0001.html
More information about the Mpls-pm
mailing list