php 和 perl 之间发送和接收数据时出现问题?
我在 php 和 perl 套接字之间发送和接收数据时遇到问题:
-问题:
- 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);
}
}
I have a problem in sending and receiving data between php and perl socket:
-Problem:
- php can not send all byte data to perl socket
- Perl socket can not receiving all data from php .
Here code 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");
}
}
Here code 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);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您忘记实际编写解析接收到的数据的代码。 TCP 是一种字节流协议,不保留应用程序消息边界。除非这恰好是您所需要的(而且显然不在这里),否则您需要在 TCP 之上开发和实现一个协议,以提供您的应用程序所需的功能。一方面,您需要某种方法来找到命令的结尾。您的代码绝对没有为接收者提供执行此操作的方法。
无论协议多么简单,您确实应该投入时间编写协议规范。协议规范应明确规定字节级别的消息格式。协议规范应明确指定客户端在拥有完整消息时如何识别。
然后您实际上必须编写代码来实现该协议。
在这种情况下,您可以简单地写入一个零字节来标记消息的结束。然后对接收器进行编码,使其继续接收数据,直到接收到零字节。然后它就知道消息之前的一切。
You forgot to actually write the code that parses the received data. TCP is a byte-stream protocol that does not preserve application message boundaries. Unless that happens to be exactly what you need (and it clearly isn't here), you need to develop and implement a protocol on top of TCP that provides the capabilities your application needs. For one thing, you need some way to find the end of a command. Your code provides absolutely no way for the receiver to do that.
You really should invest the time in writing a protocol specification, no matter how simple the protocol is. The protocol specification should clearly specify the message formats at the byte level. The protocol specification should clearly specify how the client identifies when it has a complete message.
Then you actually have to write code to implement that protocol.
In this case, you could simply write a zero byte to mark the end of a message. Then code the receiver to keep receiving data until it receives a zero byte. Then it knows everything before that is a message.