Perl IO ::套接字时序问题

时间:2010-03-01 15:37:06

标签: perl sockets

我遇到了一个奇怪的问题。我在Perl中编写了一个小守护进程,用于绑定服务器上的端口。 在同一台服务器上运行LAMP,我的Perl守护程序的客户端是一个php文件,用守护进程打开一个套接字,推送一些信息,然后关闭连接。在Perl守护程序中,我将每个连接记录在一个日志文件中以供以后使用。

我最大的问题是:在php脚本完成执行之前,有15-20秒,直到守护进程记录连接。

PHP客户端:

$sh = fsockopen("127.0.0.1", 7890, $errno, $errstr, 30);
if (!$sh) 
{
echo "$errstr ($errno)<br />\n";
} 
else 
{

    $out = base64_encode('contents');
    fwrite($sh, $out);
    fclose($sh);
}

Perl守护进程(只是套接字部分)

#!/usr/bin/perl

use strict;
use warnings;
use Proc::Daemon;
use Proc::PID::File;
use IO::Socket;
use MIME::Base64;
use Net::Address::IP::Local;

MAIN:
{
#setup some vars to be used down...
if (Proc::PID::File->running())
        {
                exit(0);
        }


        my $sock = new IO::Socket::INET(
                        LocalHost => $ip,
                        LocalPort => $port,
                        Proto => 'tcp',
                        Listen => SOMAXCONN,
                        Reuse => 1);

        $sock or die "no socket :$!";
        my($new_sock, $c_addr, $buf);

for (;;) 
        {

                # setup log file 
                open(LH, ">>".$logs);

                print "SERVER started on $ip:$port \n";
                print LH "SERVER started on $ip:$port \n";

                while (($new_sock, $c_addr) = $sock->accept())
                {
                        my ($client_port, $c_ip) =sockaddr_in($c_addr);
                        my $client_ipnum = inet_ntoa($c_ip);
                        my $client_host =gethostbyaddr($c_ip, AF_INET);

                        my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime time;
                        $year += 1900;
                        $mon += 1;
                        print "$year-$mon-$mday $hour:$min:$sec [".time()."] - got a connection from: [$client_ipnum]";

                        open(AL, ">>".$accessLog);
                        print AL "$year-$mon-$mday $hour:$min:$sec [".time()."] - got a connection from: [$client_ipnum]\n";
                        close AL;

                        while (defined ($buf = <$new_sock>))
                        {
                                print "contents:",  decode_base64($buf), " \n";
                                open(FH, ">".$basepath."file_" . time() .".txt")  or warn "Can't open ".$basepath."file_".time().".txt for writing: $!";
                                print FH decode_base64($buf);
                                close FH;
                        }
                }
                close LH;

        }

}

我做错了什么然后导致php在写入后关闭套接字和记录连接的Perl脚本之间有20秒的差距。任何的想法? 温柔,我是Perl的新手:)

2 个答案:

答案 0 :(得分:2)

$ new_sock未明确关闭,因此在接受调用之前不会关闭。这可能会导致一些事情挂起,直到达到超时。 (我不确定在接受或退出时是否会发生收盘。)

此外,您使用的是“&lt;&gt;”操作员从套接字读取数据。如果输入中没有换行符会发生什么?

查看实际情况的最佳方法是在“strace -e trace = network”下运行该过程,并尝试将网络系统调用与perl和php语句进行匹配。

答案 1 :(得分:0)

我没有看到任何冲洗缓冲区的调用,你能否检查在记录后刷新时延迟是否消失?