【问题标题】:PHP To Perl Socket CommunicationPHP 到 Perl 套接字通信
【发布时间】:2010-11-02 20:30:15
【问题描述】:

到目前为止,我已经编写了一个在后台持续运行的 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 编写的客户端,但不能 100% 使用 php,我的意思是 100% 是服务器将接收命令但无法发送它的事实返回,或者服务器能够接收命令但客户端无法读取回复。

这是我工作最多的客户端 [php]。

$handle = fsockopen("tcp://xx.xx.xx.xx",1234);
fwrite($handle,"ls");
echo fread($handle);
fclose($handle);

这是工作的 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;
    }
}

如果有帮助,我可以在需要时发布整个服务器。

【问题讨论】:

  • 哇。你真的应该试试 Net::Server,或者更好的是 AnyEvent::Socket::tcp_server。手动实现所有这些是在浪费您的时间......而且它甚至不起作用。
  • 也许您可以尝试让服务器检测错误并记录读取或写入的错误,看看该错误是否有助于诊断问题。为什么你的 perl 客户端分叉,而你的 php 客户端却没有?
  • 它看起来确实有点乱,所以我会仔细研究一下 Net::Server 和另一个。 perl 客户端分叉的原因是,当我将它从网上拉出来以快速查看它是否以这种方式工作时,就是这样。
  • “当我把它从网上拉出来的时候”——不要那样做,互联网是黑暗时代的一大片糟糕代码。
  • 你能贴出服务器的全部代码吗?

标签: php perl sockets


【解决方案1】:

您的服务器希望客户端发送线路。但是您的 PHP 客户端只发送两个字符“ls”。这意味着您的服务器将永远等待客户端发送换行符。

编辑:

  1. 您的 Perl(服务器)代码正在使用面向行的协议。你的 PHP 代码不是。您不应该混合使用两种沟通方式。
  2. 您的 Perl 客户端确实使用面向行的协议。
  3. 您的 PHP 代码应使用 fgets() 而不是 fread()
  4. 在您的服务器中,父进程保持到客户端的套接字打开。这就是为什么当孩子退出时套接字没有关闭,这可能就是为什么您的客户端在另一个客户端连接到服务器之前不会看到 EOF。

【讨论】:

  • while (defined($line = )) { print "运行命令"; ## 我们是否超过了这一点 $command = $line;打印$命令;打印“发送回复”;打印 $client $command 或 die($!);打印“回复已发送”;如果您的说法是这样,当我添加“打印标记”时,它会一直发送到回复而不会挂起或“永远等待”,还是只是跳过其他人继续前进?
  • 这是一个反问句吗?
  • 你可能在这里有缓冲作用。
  • 您应该在父进程中关闭客户端套接字。也许你的 PHP 代码似乎在等待套接字关闭,但父级只有在接受下一个连接时才会关闭它。
猜你喜欢
  • 2013-12-26
  • 2015-07-09
  • 2012-04-11
  • 2011-06-09
  • 2010-11-06
  • 1970-01-01
  • 2017-08-03
  • 1970-01-01
  • 2013-12-01
相关资源
最近更新 更多