我遇到了一个奇怪的问题。我在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的新手:)
答案 0 :(得分:2)
$ new_sock未明确关闭,因此在接受调用之前不会关闭。这可能会导致一些事情挂起,直到达到超时。 (我不确定在接受或退出时是否会发生收盘。)
此外,您使用的是“&lt;&gt;”操作员从套接字读取数据。如果输入中没有换行符会发生什么?
查看实际情况的最佳方法是在“strace -e trace = network”下运行该过程,并尝试将网络系统调用与perl和php语句进行匹配。
答案 1 :(得分:0)
我没有看到任何冲洗缓冲区的调用,你能否检查在记录后刷新时延迟是否消失?