Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Socket: I don't get what is sent

by Anonymous Monk
on Oct 17, 2002 at 12:37 UTC ( #206002=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi guys, I'm using the code from http://www.perldoc.com/perl5.6.1/lib/Sys/Syslog.html
to write a Socket-Server-Client connection. The Server sends his lines with $EOL = "\015\012", but the client just does not print anything until the server is killed?
This is my code
The SERVER:
$WaitSec = 10; # to test it's set to 10 sec # later it will be set to 60 # to wait 1 min to send next 1 min bar. @a = @ARGV; $f = (@a) ? $_[0] : "SP1Min.txt"; open (MF, "< $f") or die "can't open $f: $!"; $MIN = <MF>; #read 1. line chomp($MIN); $SEP = ''; # to set Global Seperator &startServer(); ##### subs ######### sub logmsg { print "$0 $$: > @_ < at ", scalar localtime, "\n" if $v; } sub startServer { #use strict; BEGIN { $ENV{PATH} = '/usr/ucb:/bin' } use Socket; use Carp; my $EOL = "\015\012"; my $port = shift || 2345; my $proto = getprotobyname('tcp'); ($port) = $port =~ /^(\d+)$/ or die "invalid port"; socket(Server, PF_INET, SOCK_STREAM, $proto) || die "socket: $!"; setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) || die "setsockopt: $!"; bind(Server, sockaddr_in($port, INADDR_ANY)) || die "bind: $!"; listen(Server,SOMAXCONN) || die "listen: $!"; logmsg "server started on port $port"; my $paddr; $SIG{CHLD} = \&REAPER; for ( ; $paddr = accept(Client,Server); close Client) { my($port,$iaddr) = sockaddr_in($paddr); my $name = gethostbyaddr($iaddr,AF_INET); logmsg "connection from $name [", inet_ntoa($iaddr), "] at port:$port, proto:$proto, iAdr:$iaddr"; print Client "Hello", $name, $EOL; # connected to s.o. #now send every $WaitSec one line of the file. print Client $MIN, $EOL; $t = time; while ( defined($MIN = <MF>)) { chomp($MIN); sleep ((time + $WaitSec) - $t); $t=time; print Client $MIN, $EOL; logmsg($MIN); } print Client "End of Session", $EOL; logmsg("File Ende -- Session-Ende, Good Night"); close(MF); exit; } #end for } #end sub
This server sends every 10 sec one line which is printed as well.
Here is now the Client from the same site, that shoul receive the bars and print them out for now.
use strict; use Socket; my $v = 1; my ($remote,$port, $iaddr, $paddr, $proto, $line); $remote = shift || 'localhost'; $port = shift || 2345; # random port if ($port =~ /\D/) { $port = getservbyname($port, 'tcp') } die "No port" unless $port; $iaddr = inet_aton($remote) || die "no host: $remote"; $paddr = sockaddr_in($port, $iaddr); $proto = getprotobyname('tcp'); socket(SOCK, PF_INET, SOCK_STREAM, $proto) || die "socket: $!"; connect(SOCK, $paddr) || die "connect: $!"; logmsg("3Remote:$remote, Port:$port, Proto:$proto"); # This message is print, so I do get here! # At the same tiome the server starts sending bars while (1) { $line = <SOCK>; print "\nGot1: ", $line; # until the server is killed nothing appears. # Then it prints all the time in a new line: Got1: NIX .. if ( !defined($line) ) { #if ( !defined($line = <SOCK>) ) { print "NIX, "; sleep 1; next; } else { if ($line !~ /End\sof\sSession/) { print "\nGot2: ", $line; sleep 5; next; } else { close (SOCK) || die "close: $!"; exit; } } }
I thank all who take time to read it at least for their effort, Carl

Comment on Socket: I don't get what is sent
Select or Download Code
Re: Socket: I don't get what is sent
by JaWi (Hermit) on Oct 17, 2002 at 12:44 UTC
    In your client, you should turn auto-flush on, by setting $| to a non-zero value. A snippet of how this would look like in your client code:
    ... # This message is print, so I do get here! # At the same tiome the server starts sending bars $|++; # <-- Turns on automatic flusing after each write... while (1) { $line = <SOCK>; print "\nGot1: ", $line; ...

    Update: I've been playing with the code myself, and as tye pointed out in a reply below: you need to unbuffer the Client handle at server-side! This would make your server code look like this:

    ... $SIG{CHLD} = \&REAPER; for ( ; $paddr = accept(Client,Server); close Client) { # This will correctly set the autoflushing... select( ( select(Client), $|++ )[0] ); my($port,$iaddr) = sockaddr_in($paddr); my $name = gethostbyaddr($iaddr,AF_INET); ...
    Success,

    -- JaWi

    "A chicken is an egg's way of producing more eggs."

      Thanks to all of you, but this doen't work.
      I just tried all the suggestions:
      $|++; $|=1; in the Client and in the Server.
      But my Client keeps silence, doen't print anything as long the server is running.
      By the way all what has been sent is lost. I think if it were the buffer,
      it should print the buffer as soon as the first line: "Got1: NIX," appears.
      What happened to that what was written meanwhile to the buffer?
      Carl

      $|++; # <-- Turns on automatic flusing after each write...
      No! That turns on automatic flushing after each write to STDOUT. Do one of the following:

      select( ( select(SOCK), $|++ )[0] ); # or use IO::Handle; SOCK->autoflush(1);
      Though I'm surprised that sockets don't default to being unbuffered.

              - tye (but my friends ca)
        Your right, the socket handle has to be unbuffered: however, this has to happen at server side and not client side...
        Funny however that the example in the perlipc doesn't mention this...

        -- JaWi

        "A chicken is an egg's way of producing more eggs."

Re: Socket: I don't get what is sent
by fglock (Vicar) on Oct 17, 2002 at 12:45 UTC

    Looks like a buffer problem. Try setting this, both in client and server:

    $| = 1;   # autoflush
Re: Socket: I don't get what is sent
by MZSanford (Curate) on Oct 17, 2002 at 13:00 UTC
Re: Socket: I don't get what is sent
by princepawn (Parson) on Oct 17, 2002 at 13:24 UTC
    Perhaps you should avoid trying to do socket stuff yourself and use STEM or POE
      Well,
      first I want to learn how this works to write my own stuff
      second this is not my code, it is from an official Perl-Site
      where examples of how to program socket stuff are written.
      I don't understand that those 'official examples' do not work.
      Carl
      perhaps Lincoln Steins book on Network Programming in Perl will help. Also, you can be an apprentice for Stem and help out with its development.

      Good luck!

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://206002]
Approved by JaWi
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (3)
As of 2014-11-29 10:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (204 votes), past polls