我尝试将数据从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
那么,为什么它实际上不发送数据?
答案 0 :(得分:2)
$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 -- $!"; }
while
周围需要$buff = <$listen>
才能在发送时读取多行。对于允许所有这些的多个连接,应该使用while循环。简而言之,对于您发布的示例中的单行消息
my $listen = $web->accept();
my $recd = <$listen>;
chomp($recd);
print "$recd\n";
就Perl代码而言。我不知道PHP例程是如何工作的(对我来说似乎没问题)。
虽然IO::Socket提供了基本信息,但Perl文档中还有很多内容。例如,有一个使用IO::Socket
的服务器示例
Perl IPC,在该页的最后。
如果我建议,请在开头添加use warnings;
。它实际上非常有用。我怀疑它会警告你这件事。