(fwd) Re: Sockets Client/Server

Andrey Gerzhov (kittle@freeland.alex-ua.com)
Fri, 30 Oct 1998 09:33:39 +0200 (EET)

-- forwarded message --
Path: freeland.alex-ua.com!barmaglot.alex-ua.com!f188.n463.z2!f116.n463.z2!f58.n463!f238.n5020!f400.n5020!ddt.demos.su!fido-news-server
Newsgroups: fido.ru.perl
Distribution: fido
X-Comment-To: Anatoly K. Lasareff
From: Artur Penttinen <artur@niif.spb.su>
X-FTN-Sender: Artur Penttinen <Artur.Penttinen@f400.n5020.z2.fidonet.org>
Date: Tue, 27 Oct 98 18:05:36 +0200
Subject: Re: Sockets Client/Server
Message-ID: <8iqzpaiqc51.fsf@disco.elma.fi>
References: <36345C7E.3D6D78EB@vessolink.karelia.ru> <x71znvs7ck.fsf@tolikus.hq.aaanet.ru> <36357BEC.4D801646@vessolink.karelia.ru> <x7iuh6qtju.fsf@tolikus.hq.aaanet.ru>
Organization: Private Person
X-FTN-AREA: RU.PERL
X-FTN-MSGID: disco.elma.fi d3e18d80
X-FTN-REPLY: tolikus.hq.aaanet.ru b3e16d5a
X-FTN-Tearline: ifmail v.2.14dev2
X-FTN-Origin: Private Person (2:5020/400@fidonet)
X-FTN-SEEN-BY: 50/381 502 615 993 461/121 463/5 18 58 68 89 116 159 177 188 220
X-FTN-SEEN-BY: 463/246 306 308 432 513 464/100 465/185 467/10 478/20 4614/1
X-FTN-SEEN-BY: 4615/21 4616/3 5001/211 5002/16 5003/15 5006/1 5007/1 5011/13
X-FTN-SEEN-BY: 5015/28 5020/68 118 204 238 400 443 1057 1200 1381 1851 4000 5023/1
X-FTN-SEEN-BY: 5023/11 5025/2 5029/5 5030/23 251 5032/6 5034/1 5035/10 5036/1
X-FTN-SEEN-BY: 5039/7 5040/47 5049/1 6 5054/9 5055/44 5057/1 5058/24 5060/88
X-FTN-SEEN-BY: 5061/15 5064/5 5065/10 5066/2 5067/5 5069/1 2 5074/9 5075/10
X-FTN-SEEN-BY: 5080/80 5083/61
X-FTN-PATH: 5020/400 238 463/58 116
X-FTN-PATH: 463/188
Lines: 229
Xref: freeland.alex-ua.com fido.ru.perl:292

From: tolik@icomm.ru (Anatoly K. Lasareff)
Newsgroups: fido7.ru.perl
Date: 27 Oct 1998 11:53:33 +0300

> >>>>> "AVV" == Alex V Varavva <alexv@vessolink.karelia.ru> writes:
>
> AVV> Вопрос такой - как на perl написать приложение (сервер), которое
> AVV> вешалось бы на определенный порт(сокет), получало бы данные (от
клиента)
> AVV> и затем отправляло подтверждение (клиенту) ?
> >>
> AVV> А то попадаются примеры в которых или одно или другое (только
> AVV> прием/только передача).
> >>
> >> Если ты работаешь под унихом и у тебя есть root права, то по моему
> >> проше повесить соответствующую программу в inetd - при этом сам сервер
> >> читает со стдина, и пишет на стдоут. Только надо не забыть автофлаш на
> >> стдоут.
> >>
>
> AVV> Есть права, есть unix, есть желание сделать, но не знаю как :((
> AVV> Киньте плз пример.
>
примеры клиента и сервера
-- server --------------------------------------------------
#!/usr/local/bin/perl5

$dir = "/home/elma/elma/hemmot";
$opt_d = 0;

($port) = @ARGV;
$port= 2345 unless $port;

$AF_INET = 2;
$SOCK_STREAM = 1;
$EINTR = 4;

$sockaddr = 'S n a4 x8';

sub missa1 {
local($user,$mtime) = @_;
local($message, $nro);

if (-f "$dir/$user/pois") {
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
$atime,$mtime,$ctime,$blksize,$blocks)
= stat(_);
open (POISSA,"$dir/$user/pois");
if ($message = <POISSA>) {
while (<POISSA>) {
$message .= "\t$_";
}
}
close(POISSA);
} else {
$message = "Paikalla\n"
}
if (-f "$dir/$user/nro") {
open (NRO,"$dir/$user/nro");
$nro = <NRO>;
chop($nro);
close(NRO);
} else {
$nro = ' ';
}

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($mtime);
($sec1,$min1,$hour1,$mday1,$mon1,$year1,$wday1,$yday1,$isdst1) =
localtime(time);

$dday=$yday1-$yday;
$dday+=($year1-$year)*365;

if ($dday==0) {
$ts = sprintf "%02d.%02d %02d:%02d", $mday,($mon+1),$hour,$min;
} elsif ($dday==1) {
$ts = sprintf "eilen %02d.%02d %02d:%02d", $mday,($mon+1),$hour,$min;
} elsif ($dday==2) {
$ts = sprintf "toissapnД %02d.%02d %02d:%02d", $mday,($mon+1),$hour,$min;
} else {
$ts = sprintf "%d pДivДД sitten %02d.%02d %02d:%02d",
$dday,$mday,($mon+1),$hour,$min;
}

print NS "$nro\t$user\t$ts\t$message";
($opt_d) && print "Done $user\n";
}

sub missa {
local($user) = @_;

if ($user) {
if ($user =~ /^[a-z]+$/ && -d "$dir/$user") {
local($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
$atime,$mtime,$ctime,$blksize,$blocks)
= stat(_);
missa1 ($user, $mtime);
} else {
print NS "Unknown user!\n";
}
} else {
opendir (D, "$dir/") || return;
@d = readdir (D);
closedir (D);
@d = sort (@d);
foreach $fname (@d) {
if ($fname =~ /^[a-z]+$/ && ! -l "$dir/$fname" && -d "$dir/$fname") {
local($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
$atime,$mtime,$ctime,$blksize,$blocks)
= stat(_);
missa1 ($fname, $mtime);
}
}
}
}

($name, $aliases, $proto) = getprotobyname('tcp');
if ($port !~ /^\d+$/) {
($name, $aliases, $port) = getservbyport($port, 'tcp');
}

($opt_d) && print "Port = $port\n";

$this = pack($sockaddr, $AF_INET, $port, "\0\0\0\0");

select(NS); $| = 1; select(stdout);

socket(S, $AF_INET, $SOCK_STREAM, $proto) || die "socket: $!";
bind(S,$this)|| die "bind: $!";
listen(S,5) || die "connect: $!";

select(S); $| = 1; select(stdout);

sub waitforc {
wait;
($opt_d) && printf("waited\n");
$SIG{'CHLD'} = 'waitforc';
}
$SIG{'CHLD'} = 'waitforc';

for($con = 1; ;$con++) {
($opt_d) && printf("Listening for connection %d.....\n", $con);

while (!($addr = accept(NS,S))) {
die $! unless $EINTR == $!;
}

if (($child = fork()) == 0) {
($opt_d) && print "accept ok\n";

($af, $port, $inetaddr) = unpack($sockaddr, $addr);
@inetaddr = unpack('C4',$inetaddr);
($opt_d) && print "$con: $af $port @inetaddr\n";

# jaakko 1996-06-06 no more looping, just process 1 command
if ($_ = <NS>) {
($command, $user, @args) = split;
($opt_d) && print "$con: $_";
$lookdir = "$dir/$user";
if (! -d $lookdir) {
print NS "Unknown user\n";
} elsif ($command eq "MISSA") {
missa ($user);
} elsif ($command eq "POIS") {
if (!@args) {
unlink("$lookdir/pois");
} else {
open (POISSA, ">$lookdir/pois");
print POISSA "@args\r\n";
close (POISSA);
chown (28,1,"$lookdir/pois") ;
}
}
}
close(NS);
($opt_d) && print "$con: exiting\n";
exit;
}
close(NS);
}
-- client --------------------------------------------------
#!/usr/local/bin/perl

$user = $ARGV[0];
$port = 2345 unless $port;
$them = 'localhost' unless $them;
$opt_d = 0;

# die "Usage: M <user>\n" unless $user;

$AF_INET = 2;
$SOCK_STREAM = 1;

$sockaddr = 'S n a4 x8';

chop($hostname = `hostname -s`);

($name, $aliases, $proto) = getprotobyname('tcp');
($name, $aliases, $port) = getservbyport($port, 'tcp')
unless $port =~ /^\d+$/;;
($name, $alias, $type, $len, $thisaddr) = gethostbyname($hostname);
($name, $alias, $type, $len, $thataddr) = gethostbyname($them);

$this = pack($sockaddr, $AF_INET, 0, $thisaddr);
$that = pack($sockaddr, $AF_INET, $port, $thataddr);

if (socket(S, $AF_INET, $SOCK_STREAM, $proto)) {
($opt_d) && print "socket ok\n";
} else {
die $!;
}

if (connect(S, $that)) {
($opt_d) && print "$connect ok\n";
} else {
die $!;
}

select(S); $| = 1; select (STDOUT);

print S "MISSA $user\n";
while(<S>) {print;}
close S;
--------------------------------------------------

WBW, Artur

-- end of forwarded message --

-- 
С тем, что не помешает никогда,
                                               Kittle