在php和perl之间发送和接收数据的问题?

时间:2011-11-21 03:12:31

标签: php perl

我在php和perl socket之间发送和接收数据时遇到问题:

- 问题:

  • php无法将所有字节数据发送到perl socket
  • 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 socket:

#!/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 个答案:

答案 0 :(得分:1)

您忘记实际编写解析接收数据的代码。 TCP是一种字节流协议,不保留应用程序消息边界。除非恰好是您所需要的(并且显然不在此处),否则您需要在TCP之上开发和实现一个提供应用程序所需功能的协议。首先,您需要一些方法来查找命令的结束。你的代码绝对没有办法让接收者做到这一点。

无论协议有多简单,你都应该花时间编写协议规范。协议规范应明确指定字节级的消息格式。协议规范应明确说明客户端何时识别出完整的消息。

然后你实际上必须编写代码来实现该协议。

在这种情况下,您可以简单地写一个零字节来标记消息的结尾。然后编码接收器以保持接收数据,直到它收到零字节。然后它就知道了之前的所有信息。