maxl90 has asked for the wisdom of the Perl Monks concerning the following question:

As of right now I'm just dipping into the world of sockets. What I'm trying to do is pipe output from a QNX machine using perl to a w2k machine. So far everything works. The problem is on the qnx side it is always sending information (which is good) but on the client side (w2k) it isn't appending out the info to a file in real time. To elaborate...If the client is shut down nothing is written to the file. As an overview what I’m trying to do is get the information to my w2k machine to do some heavy possessing on that data. I would like to crunch all the numbers while the info is still flowing. Here is what I’ve attempted to do so far. Does anyone have a way to solve the problem are know of a better or more proficient way of accomplishing this? here is the part of the server that is realaying information.
use IO::Socket; my $sock = new IO::Socket::INET ( LocalHost => 'qnxa227', LocalPort => '7070', Proto => 'tcp', Listen => 1, Reuse => 1 ); die "Could not creat socket: $!\n" unless $sock; $sock->autoflush(1); print "The server is up and ready\n"; my $new_sock =$sock ->accept() || die " error $new_sock"; #### This just goes around an infinite loop gathering info while(1){ sleep(2); if( $ARGV[0] eq "l"){ & short; print "\n"; & long; } elsif( $ARGV[0] eq "lp"){ & short; print "\n"; & pfilter; } else { @x = (& short( $new_sock)); print($new_sock $x[0]),"\n"; print($new_sock $x[1]),"\n"; print($new_sock $x[2]),"\n"; } } close($sock);
And here is the client side....
use IO::Socket::INET; $file = "info.txt"; #open(stdout,">>$file"); ### one way of trying to output to a file $sock = IO::Socket::INET->new( PeerAddr => '10.8.74.227', PeerPort => '7070', Proto => 'tcp'); print "client running\n"; my $byte; while (sysread($sock, $byte, 1) == 1) { print $byte; } close($sock);
Thanks A Lot!

Replies are listed 'Best First'.
Re: Sockets and Output
by Coruscate (Sexton) on Jan 15, 2003 at 23:23 UTC

    Here's one for you. The first snippet is the server, the second one is the client.

    #!c:/perl/bin/perl -w $|++; use strict; use IO::Socket::INET; # Initialize the server my $sock = new IO::Socket::INET ( LocalHost => '127.0.0.1', LocalPort => '7070', Proto => 'tcp', Listen => 1, ReuseAddr => 1 ) or die "Server could not initialize!\n\n"; # Autoflush for verisons before 1.18 $sock->autoflush(1); print "The server has successfully initialized.\n\n"; # Allow another client to connect after the # current client disconnects from the server. while ( my $new_sock = $sock->accept() ) { print "A client has connected to the server.\n"; # Example output to the client for my $i (1 .. 5) { sleep 1; print $new_sock $i, "\n"; } close $new_sock; }

    #!c:/perl/bin/perl -w $|++; use strict; use IO::Socket::INET; # Number of times to attempt a server connection my $max_attempts = $ARGV[0] || 10000; my $sock; for my $i (1 .. $max_attempts) { $sock = IO::Socket::INET->new( PeerAddr => '127.0.0.1', PeerPort => '7070', Proto => 'tcp' ); if (defined $sock) { print "Connection to server established.\n\n"; last; } else { print "Attempt $i/$max_attempts failed.\n"; die "Could not connect to the server.\n\n" if $i == $max_attempts; } sleep 2; } # Continually grab input from the server my $byte; print $byte while sysread($sock, $byte, 1); close $sock;
Re: Sockets and Output
by Thelonius (Priest) on Jan 15, 2003 at 22:53 UTC
    You need to autoflush STDOUT in your client (if you are terminating your client with ^C). Also, there's no reason to do the sysread one byte at a time. You should be able to (I haven't tested):
    while (sysread($sock, $buffer, 1024)) { print $buffer }
Re: Sockets and Output
by pg (Canon) on Jan 16, 2003 at 04:42 UTC
    To improve performance and to make the structure of your application more clear, I would suggest you to consider multi-threading.

    For example on the client side, it is better to have at least two threads running:
    1. One communication thread to communicate with the server, to read the socket.
    2. One data processing thread to process what the communication thread received.