desiv has asked for the wisdom of the Perl Monks concerning the following question:
Greetings, monks! I'm new at Perl and network programming using sockets. I've run into a problem that I can't quite make sense of regarding treating sockets as filehandles on Windows XP Pro. This has bothered me so much that tinkering around with Perl has begun to lose some of its fun! Please shed some light on this problem if you can; so far everything I've gotten stuck on with Perl has had a solution that made every bit of sense. Here goes a description of my troubles:
The client and server code below are from http://perldoc.perl.org/perlipc.html#Internet-TCP-Clients-and-Servers. The server code has been modified to echo the client's selection back over the connection instead of calling external programs.
When both the client and server are run using active state perl 5.8.8 from winxp pro
S2's command shell, the client hangs after a command is entered; when CTRL-C is entered
from the client, any "excess" commands entered during the hung state are entered to the
windows shell and executed after client termination.
Windows shell => Linux and Solaris also fails as described above.
successes?:
- I can connect to a running server via telnet in windows
- The client doesn't hang (and seems to work fine) when i use a linux system
(perl 5.8.8)
- I also have success talking between perl 5.8.5 on a solaris system and perl
5.8.8 on a linux system
- I also have success connecting from linux/solaris => windows
client:
=======
#!/usr/bin/perl -w use strict; use IO::Socket; my ($host, $port, $kidpid, $handle, $line); unless (@ARGV == 2) { die "usage: $0 host port" } ($host, $port) = @ARGV; # create a tcp connection to the specified host and port $handle = IO::Socket::INET->new(Proto => "tcp", PeerAddr => $host, PeerPort => $port) or die "can't connect to port $port on $host: $!"; $handle->autoflush(1); # so output gets there right away print STDERR "[Connected to $host:$port]\n"; # split the program into two processes, identical twins die "can't fork: $!" unless defined($kidpid = fork()); # the if{} block runs only in the parent process if ($kidpid) { # copy the socket to standard output while (defined ($line = <$handle>)) { print STDOUT $line; } kill("TERM", $kidpid); # send SIGTERM to child } # the else{} block runs only in the child process else { # copy standard input to the socket while (defined ($line = <STDIN>)) { print $handle $line; } }
server:
=======
#!/usr/bin/perl -w use IO::Socket; use Net::hostent; # for OO version of gethostbyaddr $PORT = 9000; # pick something not in use $server = IO::Socket::INET->new( Proto => 'tcp', LocalPort => $PORT, Listen => SOMAXCONN, Reuse => 1); die "can't setup server" unless $server; print "[Server $0 accepting clients]\n"; while ($client = $server->accept()) { $client->autoflush(1); print $client "Welcome to $0; type help for command list.\n"; $hostinfo = gethostbyaddr($client->peeraddr); printf "[Connect from %s]\n", $hostinfo ? $hostinfo->name : $client +->peerhost; print $client "Command? "; while ( <$client>) { next unless /\S/; # blank line if (/quit|exit/i) { last; + } elsif (/date|time/i) { print $client "SELECTED: date/time\n" +; } elsif (/who/i ) { print $client "SELECTED: who\n"; + } elsif (/cookie/i ) { print $client "SELECTED: cookie\n"; + } elsif (/motd/i ) { print $client "SELECTED: motd\n"; + } else { print $client "Commands: quit date who cookie motd\n"; } } continue { print $client "Command? "; } close $client; }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Windows TCP socket client hangs in perlipc code
by BrowserUk (Patriarch) on Oct 19, 2007 at 23:29 UTC | |
|
Re: Windows TCP socket client hangs in perlipc code
by liverpole (Monsignor) on Oct 19, 2007 at 23:45 UTC | |
by Anonymous Monk on Oct 20, 2007 at 00:46 UTC | |
by liverpole (Monsignor) on Oct 20, 2007 at 13:39 UTC |