пятница, 18 мая 2012 г.

Cвязка клиент - сервер по XML

Сервер (1.1.1.1):
 
#!/usr/bin/perl

use strict;
use warnings;
use diagnostics;

use POSIX;

use IO::Socket;
use XML::Simple;
use Text::Iconv;

use Data::Dumper;

my $settings = {
    'user' => "smsd",
    'group' => "smsd",
    'port' => 22457,
    'outgoing_dir' => '/var/spool/sms/outgoing/',
    'logfile' => '/var/log/smstools/zabbix_smsd.log',
};


# Резолвим идентификаторы пользователя и группы
my $d_uid = getpwnam($settings->{'user'});
my $d_gid = getgrnam($settings->{'group'});

# Урезаем права
setuid($d_uid);
setgid($d_gid);

# Создаём сокет
my $sock = new IO::Socket::INET (
    LocalPort => $settings->{'port'},
    Proto => 'tcp',
    Listen => 1,
    Reuse => 1,
);

# Обрабатываем входящие соединения
while (my $client = $sock->accept()) {
    # IP-адрес клиента
    my $client_ip = $client->peerhost;
    # Считываем данные с клиента
    my $xml_data = "";
    while (<$client>) {
        $xml_data .= $_;
    }

    # Пытаемся распарсить данные
    eval {
        my $data = XMLin($xml_data);

        # Если данные указаны
        if (defined($data->{'number'}) && defined($data->{'message'})) {
            # Имя файла для записи SMS
            my $uniq_name = time();
            my $sms_file_name = $settings->{'outgoing_dir'} . $uniq_name;

            # Перекодируем сообщение
            my $converter = Text::Iconv->new('UTF-8', 'UCS-2BE');
            my $message = $converter->convert($data->{'message'});

            # Извлекаем номер
            my $number = $data->{'number'};

            # Формируем SMS-сообщение
            my $sms_data = "To: $number\nAlphabet: UCS2\n\n$message";

            # Печатаем сообщение в файл
            open SMSFILE, '>', $sms_file_name;
            print SMSFILE $sms_data;
            close SMSFILE;

            # Формируем сообщение для записи в лог
            my $logtime = strftime("%Y-%m-%d %H:%M:%S", localtime());
            my $logline = "$logtime $client_ip $number $uniq_name\n";

            # Пишем в лог
            open LOGFILE, '>>', $settings->{'logfile'};
            flock LOGFILE, 2;
            print LOGFILE $logline;
            close LOGFILE;
        }
    };

    # Если произошла ошибка то не расстраиваемся
    if (my $error = $@) {
    }
}

# Закрываем сокет
close($sock);

Клиент (1.1.1.2):


#!/usr/bin/perl

use strict;
use warnings;
use warnings;

use IO::Socket;
use XML::Simple;

use Data::Dumper;


# Настройки
my $settings = {
    'host' => '1.1.1.1',
    'port' => 22457,
};

# Если количество аргументов не равняется трём:
exit 1 if @ARGV != 3;

# Извлекаем данные
my $number = shift @ARGV;
my $subject = shift @ARGV;
my $body = shift @ARGV;

# Создаём структуру данных
my $data = {
    'number' => $number,
    'message' => $body,
};

# Создаём строку данных
my $data_line = XMLout(
    $data,
    'RootName' => 'xml',
    'NoAttr' => 1
);


# Создаём сокет
my $sock = new IO::Socket::INET (
    PeerAddr => $settings->{'host'},
    PeerPort => $settings->{'port'},
    Proto => 'tcp',
);

# Пишем строку данных в сокет
print $sock $data_line;

# Закрываем сокет
close $sock;

Комментариев нет:

Отправить комментарий