将数据从 Web 服务器发送到 perl 套接字侦听器


Send data from web server to perl socket listener

我尝试将数据从php web脚本发送到本地perl套接字侦听器。下面是 perl 服务器代码:

#!/usr/bin/perl
use IO::Socket::INET;
use strict;
$| = 1;
my $web = new IO::Socket::INET (
    LocalHost => '127.0.0.1',
    LocalPort => '9001',
    Proto => 'tcp',
    Listen => 5,
    Reuse => 1
) or die "ERROR in Socket Creation : $!'n";
while ($web->accept()) {
    my $web_address = $web->peerhost();
    my $web_port = $web->peerport();
    print "Accepted New Web Client Connection From : $web_address, $web_port'n";
    my $data = <$web>;
    chomp ($data);
    print "Data from web: $data'n";
}

这是php代码:

if(!($sock = socket_create(AF_INET, SOCK_STREAM, 0)))
{
    $errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);
    die("Couldn't create socket: [$errorcode] $errormsg 'n");
}
echo "Socket created 'n";
if(!socket_connect($sock , '127.0.0.1' , 9001))
{
    $errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);
    die("Could not connect: [$errorcode] $errormsg 'n");
}
echo "Connection established 'n";
$message = "GET / HTTP/1.1'r'n'r'n";
if( !socket_send ($sock , $message , strlen($message) , 0))
{
    $errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);
    die("Could not send data: [$errorcode] $errormsg 'n");
}
echo "Message send successfully 'n";

这是perl脚本的输出:

Accepted New Web Client Connection From : , 
Data from web:

这是 php 脚本的输出:

Socket created 
Connection established 
Message send successfully

那么,为什么它实际上不发送数据呢?

$web->accept()仅创建并返回一个对象,该对象可用于读取句柄(用于套接字)。 你试图用$web本身来阅读,但它做不到。换句话说,<$web>不会从套接字读取。PHP 客户端已发送其消息,该消息位于缓冲区中等待读取。

此外,当PHP客户端打印时,它正在填满缓冲区,因为另一端没有任何东西清空它(读取)。如果它在某一点打印足够多,缓冲区将变满,下一次打印将挂起,只是等待。当缓冲区未按顺序读取时,这是常见的错误来源。

您的代码需要小的更改

if ( my $listen = $web->accept() ) {
    my ($buff, $recd);
    while (defined($buff = <$listen> ) { 
        chomp($recd = $buff);
        # process the line in $recd
    }
} else { warn "Error with the socket  -- $!"; }

发送时,需要$buff = <$listen>周围的while来读取多行。 对于您允许的多个连接,所有这些都应该在 while 循环中,您拥有它。简而言之,对于您发布的示例中的单行消息

my $listen = $web->accept();
my $recd = <$listen>;
chomp($recd);
print "$recd'n";

这是Perl代码所要做的。 我不知道PHP例程是如何工作的(它们对我来说似乎没问题)。

虽然 IO::Socket 提供了基本信息,但 Perl 文档中还有更多内容。 例如,有一个服务器示例使用 IO::SocketPerl IPC,在该页面的最后。

请在开头添加use warnings;。 它实际上非常有用。 我怀疑它会警告你这一点。