Учусь программировать на Perl, поэтому решил сделать программу, способную по сети выполнять команды на другом компьютере.
С открытием соединения и подключением клиента к серверу нет проблем. Проблемы с отправкой-получением данных. Через один полнодуплексный сокет построчно:
- Клиент посылает команду серверу
- Сервер возвращает результат
Так клиент и сервер должны по очереди отправлять друг другу строки.
Примеры и исходники из интернета не работают, везде написано одно и то же (слово в слово) и посылается только 1 команда только с 1 ответом, после чего и клиент и сервер закрывают сокет.
Вот что в данный момент написано:
Сервер
#!/usr/bin/perl
#use strict;
#BEGIN { $ENV{PATH} = '/usr/ucb:/bin' }
use Socket;
my $EOL = "\015\012";
$prompt = "Prompt:";
sub logmsg { print "$0 $$: @_ at ", scalar localtime, "\n" }
#$remote = shift || 'localhost';
my $port = shift || 2345;
my $proto = getprotobyname('tcp');
($port) = $port =~ /^(\d+)$/ or die "invalid port";
socket(out, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
setsockopt(out, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) || die "setsockopt: $!";
#bind(Server, sockaddr_in($port, INADDR_ANY)) || die "bind: $!";
bind(out, sockaddr_in($port, INADDR_LOOPBACK)) || die "bind: $!";
listen(out,SOMAXCONN) || die "listen: $!";
logmsg "server started on port $port";
#$SIG{CHLD} = \&REAPER;
for ( ; $paddr = accept(in,out); ) {
($port,$iaddr) = sockaddr_in($paddr);
$name = gethostbyaddr($iaddr,AF_INET);
logmsg "connection from $name [",inet_ntoa($iaddr), "]at port $port";
#print in "Hello there, $name, it's now ",scalar localtime, $EOL;
#print in $prompt,$EOL;
print in '$ ';
$data = <in>;
#$count = sysread(in, $data, 1024);
print $data;
print in "HURA!\n";
# if ($data == "hello$EOF") { print "HURA!"; };
# while (recv(out, $command, 4, 0)) {
# print 'recv';
# print in "\$ $command";
# };
}
print "HURA!\n";
close in;
Клиент
#!/usr/bin/perl
#use strict;
use Socket;
#my ($remote,$port, $iaddr, $paddr, $proto, $line);
my $EOL = "\015\012";
$prompt = "Prompt1:";
$remote = shift || 'localhost';
$port = shift || 2345;
if ($port =~ /\D/) { $port = getservbyname($port, 'tcp') }
die "No port" unless $port;
$iaddr = inet_aton($remote) || die "no host: $remote";
$paddr = sockaddr_in($port, $iaddr);
$proto = getprotobyname('tcp');
socket(in, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
connect(in, $paddr) || die "connect: $!";
#$pipe STDIN,in;
$work_continue = 1;
do {
sysread(in, $data, 3); print $data;
# print '$ '; # выводим приглашение
#$s = <>; print in $s; # ожидаем ввода строки и посылаем ее серверу строку
send(in, "hello", 0);
@output = <in>;
print join(" ", @output);
} while ($work_continue);
#die "port $port open not shell" unless (<in> == $prompt);
#print STDOUT "Success\n";
#while (<in>) { print;
#while (<STDIN>);
#};
close (in) || die "close: $!";
exit;