我在php和perl socket之间发送和接收数据时遇到问题:
- 问题:
这里代码为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);
}
}
答案 0 :(得分:1)
您忘记实际编写解析接收数据的代码。 TCP是一种字节流协议,不保留应用程序消息边界。除非恰好是您所需要的(并且显然不在此处),否则您需要在TCP之上开发和实现一个提供应用程序所需功能的协议。首先,您需要一些方法来查找命令的结束。你的代码绝对没有办法让接收者做到这一点。
无论协议有多简单,你都应该花时间编写协议规范。协议规范应明确指定字节级的消息格式。协议规范应明确说明客户端何时识别出完整的消息。
然后你实际上必须编写代码来实现该协议。
在这种情况下,您可以简单地写一个零字节来标记消息的结尾。然后编码接收器以保持接收数据,直到它收到零字节。然后它就知道了之前的所有信息。