Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Tailing a file to a TCP socket

by kmugglet (Initiate)
on Aug 01, 2001 at 20:21 UTC ( [id://101433]=perlquestion: print w/replies, xml ) Need Help??

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

I'm trying to send the output of logfile on an NT machine to a TCP client on a Unix machine.
I've spliced the following script together from the O'Reilly Perl cookbook.
#!/usr/bin/perl -w require 5.002; use strict; BEGIN { $ENV{PATH} = '/usr/ucb:/bin' } use Socket; use Carp; use IO::File; use IO::Handle; sub logmsg { print "$0 $$: @_ at ", scalar localtime, "\n" } my $port = 8068; my $proto = getprotobyname('tcp'); my $naptime = 1; my $LOGFILE; my $curpos; open ($LOGFILE, 'c:\logfile\log') or die "Can't open logfile: $!"; socket(Server, PF_INET, SOCK_DGRAM, $proto) or die "socket: $!"; setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) or die "setsockopt:$!"; bind(Server, sockaddr_in($port, INADDR_ANY)) or die "bind: $!"; listen(Server,SOMAXCONN) or 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"; for (;;) { my $msg= ''; for ($curpos = tell($LOGFILE); <$LOGFILE>; $curpos = tell($LOGFILE)) { readline $LOGFILE; $msg = $_; print Client $msg; } sleep $naptime; seek($LOGFILE, $curpos, 0); } }
It works with quick updates, but not if the logfile is updated very rarely. It seems as if the script buffers the message before sending.
can anyone see any glaring mistakes?
Please be gentle , its my first time :-)

Replies are listed 'Best First'.
Re: Tailing a file to a TCP socket
by suaveant (Parson) on Aug 01, 2001 at 21:24 UTC
    try changing your seek($LOGFILE, $curpos, 0); to a seek($LOGFILE,0,1); to simply reset the EOF without changing your position... maybe that will help

    Update in doing so you shouldn't need the tells and starage of curpos any more...

                    - Ant

Re: Tailing a file to a TCP socket
by tadman (Prior) on Aug 01, 2001 at 22:00 UTC
    That's the way to do it using traditional system calls. You can make your life a lot easier using IO::Socket. For instance, here's the preamble in your program:
    use IO::Socket::INET; my $socket = new IO::Socket::INET ( LocalPort => 8069, Proto => 'tcp', Listen => SO_MAXCONN); while ($client_socket = $socket->accept()) { print "Connection received from ",$client_socket->peerhost()," +\n"; # Do stuff with the $client_socket... }
    You've assigned $SIG{CHLD}, which implies that you're doing some kind of fork(), but this is not done. Maybe this was stripped from the example. If you're not forking, you won't need it.

    As for a "tail -f" equivalent in Perl, try this:
    $good = 1; while ($good) { while (<$LOGFILE>) { $client_socket->print($_) || $good = 0; } seek ($LOGFILE, 0, 1); sleep 1; }
    There is a lot of other things you will want to handle if you are using more than one connection, but this is the basics.
Re: Tailing a file to a TCP socket
by IndyZ (Friar) on Aug 01, 2001 at 22:40 UTC
    Here's how I like to do it. You need to have the always versatile netcat program installed (http://www.l0pht.com/~weld/netcat/), and the "tail" utility, which is included in Cygwin and other bundles of Unix commands for Windows (I can't remember where mine came from). On the receiving Unix box, run
    nc -l -p 2000
    On the Windows box, run
    tail -f c:\logfile.txt | nc unixbox 2000
    Replace 2000 with the port number that you want to use, and unixbox with the actual address of the Unix box.

    I know, this doesn't use Perl, but it does everything that your example script did, and with only two lines of "code." Plus, you get to use netcat, which has tons of other uses, and no sysadmin should be without it.

    --
    IndyZ

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (7)
As of 2024-03-28 10:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found