我的目标:实现套接字编程,使客户端尝试连接到服务器,如果服务器没有安装在远程机器上,客户端(主机)在其部分传输一个tar文件到服务器(目标)机器和一个Perl脚本。这个Perl脚本untar文件夹,并运行一个脚本(服务器Perl脚本),现在的问题是:此服务器脚本必须永远运行(多个客户端),直到计算机重新启动或发生意外。因此,脚本可以正常运行:但由于它是连续运行的控制不会回到客户端,客户端将再次尝试连接到服务器(在一些预定义的套接字),所以基本上我希望以某种方式运行服务器,但把控制带回我的主机,在这种情况下是客户端。
代码如下:
my $sourcedir = "$homedir/host_client/test.tar";
my $sourcedir2 = "$homedir/host_client/sabkuch.pl";
my $remote_path = "/local/home/hanmaghu";
# Main subroutines
my $ssh = Net::OpenSSH->new ( $hostmachine, user =>$username, password => $password);
$ssh->scp_put($sourcedir,$sourcedir2,$remote_path)
or die "scp failed \n" . $ssh->error;
# test() is similar to system() in perl openssh package
my $rc = $ssh->test('perl sabkuch.pl');
# check if test function returned or not -> this is never executed
if ($rc == 1) {
print "test was ok , server established \n";
}
else {
print "return from test = $rc \n";
}
exit;
调用服务器脚本的另一个脚本是:
#!/usr/bin/perl
use strict;
use warnings;
system('tar -xvf test.tar');
exec('cd utpsm_run_automation && perl utpsm_lts_server.pl');
#system('perl utpsm_lts_server.pl');
# Tried with system but in both cases it doesn't return,
# this xxx_server.pl is my server script
exit;
服务器脚本为:
#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket::INET;
#flush after every write
$| =1;
my $socket = new IO::Socket::INET (
LocalHost => '0.0.0.0',
LocalPort => '7783',
Proto => 'tcp',
Listen => 5,
Reuse => 1
);
die "cannot create socket $! \n" unless $socket;
print "server waiting for client on port $socket->LocalPort \n";
while (1)
{
# waiting for new client connection
my $client_socket = $socket->accept();
# get info about new connected client
my $client_address = $client_socket->peerhost();
my $client_port = $client_socket->peerport();
print "connection from $client_address:$client_port \n";
# read upto 1024 characters from connected client
my $data = "";
$client_socket->recv($data,1024);
print "rceeived data = $data";
# write response data to the connected client
$data = "ok";
$client_socket->send($data);
# notify client response is sent
shutdown($client_socket,1);
}
$socket->close();
请帮助执行此操作:在设计方面,这是我想要的,但在实现时有这个问题,我能做一些其他的工作方法吗?
2条答案
按热度按时间7fyelxc51#
简而言之,您的“驱动程序”
sabkuch.pl
使用exec
启动服务器--它永远不会返回。“exec”函数执行系统命令,从不返回;...
(重点来自引用的文档。)一旦使用了
exec
,在进程中运行的程序就会被另一个程序 * 替换 *,请参见exec wiki
。如果该服务器继续运行您拥有的exit
,则永远无法访问,除非出现错误。请参见上面链接的Perl的exec
。因此,您的
$ssh->test()
将永远阻塞(直到服务器以某种方式退出)。这将启动一个单独的子shell并在其中生成
sabkuch.pl
,然后返回控制,test
可以完成。(服务器),无限期运行。参见perlipc中的后台进程。也可以在perlfaq 8中看到它。以及那里的许多好的链接。注意,如果sabkuch.pl
可以成为可执行的,就不需要perl ...
。Net::OpenSSH
是否有执行命令的方法,这样它就不会阻塞。通常情况下,分叉时的一个问题是wait的子项。如果我们不想这样做,可以通过 * 双重分叉 * 或处理SIGCHLD来解决请研究上面链接的
perlfaq8
、perlipc中的信号、所有使用的调用的文档,在这种情况下,父进程应该首先退出,然后子进程由init
重新成为父进程,这样一切就都好了。艾德进程获得相同的$pid
,但由于cd
将触发shell(sh -c cd
),因此服务器最终将使用不同的PID运行。有了
system('command &')
,我们就不用担心等待孩子了。这只与您的直接问题有关,与所示代码的其余部分无关。
h7appiyu2#
我认为最好的方法是派生出一个子进程,并且存在父进程,这样子进程就可以永远运行server.pl
但是它仍然不工作,请让我知道在这个代码中我哪里出错了
输出是我的脚本仍然挂起和打印语句“在儿童现在执行“得到运行两次,我不明白为什么,我的工作主要是汇编语言,因此这一切对我来说是新的。帮助将不胜感激。