PHP到Perl套接字通信

PHP到Perl套接字通信,php,perl,sockets,Php,Perl,Sockets,到目前为止,我已经编写了一个Perl服务器,它经常在后台运行,当它接收到入站连接时,一个进程被分叉,然后处理这个连接。我最终希望它能够通过套接字接受入站php连接,当然,运行这些命令,然后将信息转发回来。到目前为止,我已经成功地在Perl脚本客户端上100%工作,但在php客户端上却无法100%工作 [此处不是粘贴文本的孔壁,而是实际的发送和接收部分。] print "Binding to port ...\n"; $server = IO::Socket::INET->new(

到目前为止,我已经编写了一个Perl服务器,它经常在后台运行,当它接收到入站连接时,一个进程被分叉,然后处理这个连接。我最终希望它能够通过套接字接受入站php连接,当然,运行这些命令,然后将信息转发回来。到目前为止,我已经成功地在Perl脚本客户端上100%工作,但在php客户端上却无法100%工作

[此处不是粘贴文本的孔壁,而是实际的发送和接收部分。]

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”。这意味着您的服务器将永远等待客户端发送换行

编辑:

  • 您的Perl(服务器)代码使用的是面向行的协议。您的PHP代码不是。你不应该把两种交流方式混在一起
  • 您的Perl客户端确实使用了面向行的协议
  • PHP代码应该使用
    fgets()
    而不是
    fread()
  • 在您的服务器中,父进程使客户端的套接字保持打开状态。这就是为什么当子进程退出时套接字不会关闭的原因,这可能就是为什么在另一个客户端连接到服务器之前,您的客户端不会看到EOF

  • 哇!您应该真正尝试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;
        }
    }