Я пытаюсь отправить данные из веб-скрипта php на локальный прослушиватель сокета 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 -- $!"; }
В 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;
в начале. Это на самом деле очень полезно. Я подозреваю, что это предупредило бы вас об этом.