Программы инвертирующего эхо-сервера. Ниже описана усовершенствованная версия программы инвертирующего эхо-сервера. Новая версия не только элегантнее, но и во многом превосходит предшествующую версию. В ней потенциально опасный обработчик сигнала заменен обработчиком, который просто устанавливает флажок и выполняет возврат. Это позволяет избежать проблем, вытекающих из выполнения вызовов функций ввода-вывода в обработчике, и проблем, связанных с вызовом функции exit() на платформах Windows. Еще одно усовершенствование состоит в том, что сервер выполняет преобразование имен для входящих соединений и выводит имя удаленного хоста и номер порта на стандартное окно вывода сообщений об ошибках.
И наконец, соблюдается соглашение Internet о том, что в серверах для обозначения конца строки должна применяться последовательность CRLF. Это значит, что переменная $/ будет установлена равной CRLF и к концу каждой из выводимых строк будут добавляться символы CRLF. Код усовершенствованного сервера приведен ниже.
0
#! /usr/bin/perl
1
2
3
use strict;
4
use IO::Socket qw(:DEFAULT :crlf);
5
use constant MY ECHO PORT => 2007;
6
$/ = CRLF;
7
my ($bytes_out,$bytes_in) = (0,0);
8
my $quit =0;
9
$SIG {INT} = sub { $quit++ };
10
my $port = shift | | MY_ECHO_PORT;
11
my $sock = IO::Socket::INET->new(Listen =>
20,
12
LocalPort =>
$port,
13
Timeout =>
60*60,
14
Reuse =>
1)
15
or die "Can’t create listening socket: $!n";
16
warn "waiting for incoming connections on port
$pqrt. . An"
17
while (!$quit) {
18
nextunless my $session = $sock->accept;
19
my $peer = gethostbyaddr ($session->peeraddr, AF_ $session->peerhost;
INET);
20
my $port = $session->peerport;
21
warn "Connection from [$peer,$port]n";
22
while (<$session>) {
23
$bytes_in += length($_);
24
chomp;
25
my $msg_out = (scalar reverse $_) . CRLF;
26
print $session $msg_out;
27
$bytes out += length($msg_out);
28
}
29
warn "Connection from [$peer,$port] finishedn”;
30
close $session;
31
}
32
print STDERR "bytes sent = $bytes_out, bytes_received = $bytes_inn";