PHP到Perl套接字通信
到目前为止,我已经编写了一个Perl服务器,它经常在后台运行,当它接收到入站连接时,一个进程被分叉,然后处理这个连接。我最终希望它能够通过套接字接受入站php连接,当然,运行这些命令,然后将信息转发回来。到目前为止,我已经成功地在Perl脚本客户端上100%工作,但在php客户端上却无法100%工作 [此处不是粘贴文本的孔壁,而是实际的发送和接收部分。]PHP到Perl套接字通信,php,perl,sockets,Php,Perl,Sockets,到目前为止,我已经编写了一个Perl服务器,它经常在后台运行,当它接收到入站连接时,一个进程被分叉,然后处理这个连接。我最终希望它能够通过套接字接受入站php连接,当然,运行这些命令,然后将信息转发回来。到目前为止,我已经成功地在Perl脚本客户端上100%工作,但在php客户端上却无法100%工作 [此处不是粘贴文本的孔壁,而是实际的发送和接收部分。] print "Binding to port ...\n"; $server = IO::Socket::INET->new(
print "Binding to port ...\n";
$server = IO::Socket::INET->new(
Listen => 1,
LocalAddr => $_server,
LocalPort => $_port,
Proto => 'tcp',
Reuse => 1, Type => SOCK_STREAM) || die "Cant bind :$@\n";
$proccess = fork();
if ($proccess) {
kill(0);
}
else {
while(1) {
while ($client = $server->accept()) {
$client->autoflush(1);
$con_handle = fork();
if ($con_handle) {
print "Child Spawned [$con_handle]\n";
}else{
while (defined($line = <$client>)) {
$command = `$line`;
print $client $command;
}
exit(0);
}
}
}
下面是正在工作的perl客户机
#!/usr/bin/perl -w
use strict;
use IO::Socket;
my ($host, $port, $kidpid, $handle, $line);
unless (@ARGV == 2) { die "usage: $0 host port" }
($host, $port) = @ARGV;
# create a tcp connection to the specified host and port
$handle = IO::Socket::INET->new(Proto => "tcp",
PeerAddr => $host,
PeerPort => $port)
or die "can't connect to port $port on $host: $!";
$handle->autoflush(1); # so output gets there right away
print STDERR "[Connected to $host:$port]\n";
# split the program into two processes, identical twins
die "can't fork: $!" unless defined($kidpid = fork());
# the if{} block runs only in the parent process
if ($kidpid) {
# copy the socket to standard output
while (defined ($line = <$handle>)) {
print STDOUT $line;
}
kill("TERM", $kidpid); # send SIGTERM to child
}
# the else{} block runs only in the child process
else {
# copy standard input to the socket
while (defined ($line = <STDIN>)) {
print $handle $line;
}
}
#/usr/bin/perl-w
严格使用;
使用IO::Socket;
我的($host、$port、$kidpid、$handle、$line);
除非(@ARGV==2){die“用法:$0主机端口”}
($host,$port)=@ARGV;
#创建到指定主机和端口的tcp连接
$handle=IO::Socket::INET->new(Proto=>“tcp”,
PeerAddr=>$host,
PeerPort=>$port)
或者“无法连接到$host:$!”上的端口$port”;
$handle->autoflush(1);#所以输出马上就到了
打印STDERR“[连接到$host:$port]\n”;
#将程序分为两个进程,同卵双胞胎
除非定义($kidpid=fork()),否则die“不能分叉:$!”;
#if{}块仅在父进程中运行
如果($kidpid){
#将套接字复制到标准输出
while(已定义($line=)){
打印标准输出$行;
}
kill(“TERM”,$kidpid)#将SIGTERM发送给孩子
}
#else{}块仅在子进程中运行
否则{
#将标准输入复制到套接字
while(已定义($line=)){
打印$handle$行;
}
}
如果有帮助,我可以在需要时发布整个服务器。您的服务器希望客户端发送线路。但是您的PHP客户端只发送两个字符“ls”。这意味着您的服务器将永远等待客户端发送换行 编辑:
fgets()
而不是fread()
哇!您应该真正尝试Net::Server,或者更好的是,尝试AnyEvent::Socket::tcp\U服务器。手动实现所有这些都是对时间的巨大浪费。。。也许你可以尝试让服务器检测错误并记录读写错误,看看错误是否有助于诊断问题。为什么你的perl客户端会分叉,而你的php客户端不会呢?看起来确实有点乱,所以我可能会研究Net::Server和另一个。perl客户端分叉的原因是,当我将其从网络中拉出以快速查看其工作方式时,情况就是这样。“当我将其从网络中拉出时”--不要这样做,互联网是黑暗时代的大量垃圾代码。你能为服务器发布整个代码吗?while(defined($line=){print“Running Command”###我们是否越过这一点$command=
$line
;print$command;print“Sending reply”;print$client$command或die($!);print“reply sent”;}如果你说的是这样的话,那么当我添加“print markers”时,它会一直到reply sent而不挂起或“永远等待”吗或者它只是跳过了其他的然后继续?这是一个反问吗?这里可能有缓冲。你应该在父进程中关闭客户端套接字。也许您的PHP代码似乎在等待套接字关闭,但是父级只有在接受下一个连接时才会关闭它。
#!/usr/bin/perl -w
use strict;
use IO::Socket;
my ($host, $port, $kidpid, $handle, $line);
unless (@ARGV == 2) { die "usage: $0 host port" }
($host, $port) = @ARGV;
# create a tcp connection to the specified host and port
$handle = IO::Socket::INET->new(Proto => "tcp",
PeerAddr => $host,
PeerPort => $port)
or die "can't connect to port $port on $host: $!";
$handle->autoflush(1); # so output gets there right away
print STDERR "[Connected to $host:$port]\n";
# split the program into two processes, identical twins
die "can't fork: $!" unless defined($kidpid = fork());
# the if{} block runs only in the parent process
if ($kidpid) {
# copy the socket to standard output
while (defined ($line = <$handle>)) {
print STDOUT $line;
}
kill("TERM", $kidpid); # send SIGTERM to child
}
# the else{} block runs only in the child process
else {
# copy standard input to the socket
while (defined ($line = <STDIN>)) {
print $handle $line;
}
}