Olga Pshenichnikova
Olga Pshenichnikova

Reputation: 1581

Send data from web server to perl socket listener

I try to send data from php web script to local perl socket listener. Here is perl server code:

#!/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";
}

And here is php code:

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";

Here is output of perl script:

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

And here is output of php script:

Socket created 
Connection established 
Message send successfully

So, why it actually don't send the data?

Upvotes: 1

Views: 446

Answers (1)

zdim
zdim

Reputation: 66873

The $web->accept() only creates and returns an object, which can be used to read the handle (for the socket). You are attempting to read with $web itself, which it cannot do. In other words, <$web> does not read from the socket. The PHP client has sent its message which is sitting in the buffer waiting to be read.

Further, as the PHP client prints it is filling up the buffer, since nothing is emptying it (reading) on the other end. If it prints enough at one point the buffer will get full and the next print will hang, just waiting. This is a common source of errors, when the buffer is not being read from orderly.

Your code needs small changes

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  -- $!"; }

The while around $buff = <$listen> is needed to read more than one line as they are sent. For multiple connections that you allow all of this should be in a while loop, which you have. In a nutshell, for the one-line-message in your posted example

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

This is as far as Perl code goes. I don't know how PHP routines work (they seem to be OK to me).

While IO::Socket provides basic information, there is a lot more scattered around Perl documentation. For example, there is a server example using IO::Socket in Perl IPC, by the very end of that page.

Please add use warnings; at the beginning. It is actually extremely useful. I suspect that it would have warned you of this.

Upvotes: 2

Related Questions