Проблемы с отправкой и получением данных между php и perl? - PullRequest
1 голос
/ 21 ноября 2011

У меня проблема с отправкой и получением данных между php и perl socket:

-задача:

  • php не может отправить все байтовые данные в сокет perl
  • Сокет Perl не может получать все данные с php.

Здесь код php:

function save(){ 
    unset($_SESSION['info']); 
    unset($_SESSION['data']); 
    global $config,$ip; 
    $start=$_POST['config']; 
    $fp = fsockopen($_SESSION['ip'], $config['port'], $errno, $errstr, 30); 
    if(!$fp) { 
        $_SESSION['info']="Not connect "; 
        transfer("Not   connect".$ip, "index.php?com=server&act=info"); 
    } else { 
        $_SESSION['info']="Save config - ".$ip; 
        fwrite($fp,$start); 
        transfer("Sending data to ".$ip, "index.php?com=server&act=info");    
    } 
}

Здесь код Perl сокета:

#!/usr/bin/perl 
use strict; 
use warnings; 
use Carp; 
use POSIX qw( setsid ); 

use IO::Socket; 

$| = 1; 

my $socket = new IO::Socket::INET ( 
                              LocalHost => '192.168.150.3', 
                              LocalPort => '5000', 
                              Proto => 'tcp', 
                              Listen => 5, 
                              Reuse => 1 
                           ); 
die "Coudn't open socket" unless $socket; 
print "\nTCPServer Waiting for client on port 5000"; 
my $client_socket = ""; 
while ($client_socket = $socket->accept()) { 
    my $recieved_data =" "; 
    my $send_data=" "; 
    my $peer_address = $client_socket->peerhost(); 
    my $peer_port = $client_socket->peerport(); 
    print "\n I got a connection from ( $peer_address , $peer_port ) "; 
    print "\n SEND( TYPE q or Q to Quit):"; 
    $client_socket->recv($recieved_data,20000); 
    #while (defined($recieved_data = <$client_socket>)) { 
        if ( $recieved_data eq 'q' or $recieved_data eq 'Q' ) { 
            close $client_socket; 
            last; 
        } 
        elsif ($recieved_data eq 'start' or $recieved_data eq 'START' ) { 
            $send_data = `/etc/init.d/squid start`; 
        } 
        elsif ($recieved_data eq 'restart' or $recieved_data eq 'RESTART' ) { 
            $send_data =  `/etc/init.d/squid restart`; 
        } 
        elsif ($recieved_data eq 'stop' or $recieved_data eq 'STOP' ) { 
            $send_data =  `/etc/init.d/squid stop`; 
        } 
        elsif ($recieved_data eq 'hostname' or $recieved_data eq 'HOSTNAME' ) {
            $send_data= `hostname`; 
        } 
        elsif ($recieved_data eq 'view-config' or $recieved_data eq 'VIEW-CONFIG' ) { 
            $send_data = `cat /etc/squid/squid.conf` ; 
        } 
        else { 
            #print  $recieved_data; 
            open OUTPUT_FILE, '> /root/data' or die("can not open file"); 
            print OUTPUT_FILE $recieved_data; 
            close OUTPUT_FILE 
        } 
    #} 
    if ($send_data eq 'q' or $send_data eq 'Q') { 
        $client_socket->send ($send_data); 
        close $client_socket; 
        last; 
    } 
    else { 
        $client_socket->send($send_data); 
    } 
}

1 Ответ

1 голос
/ 21 ноября 2011

Вы действительно забыли написать код, который анализирует полученные данные.TCP является протоколом потока байтов, который не сохраняет границы сообщений приложения.Если это не то, что вам нужно (а этого явно нет), вам нужно разработать и внедрить протокол поверх TCP, который предоставляет возможности, необходимые вашему приложению.Во-первых, вам нужен какой-то способ найти конец команды.Ваш код не дает получателю абсолютно никакой возможности сделать это.

Вы действительно должны потратить время на написание спецификации протокола, независимо от того, насколько он прост.Спецификация протокола должна четко указывать форматы сообщений на уровне байтов.Спецификация протокола должна четко указывать, как клиент идентифицирует, когда у него есть полное сообщение.

Тогда вам действительно нужно написать код для реализации этого протокола.

В этом случае вы можете просто написатьнулевой байт, чтобы отметить конец сообщения.Затем закодируйте получатель, чтобы он продолжал получать данные до тех пор, пока он не получит нулевой байт.Тогда он знает все, прежде чем это сообщение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...