Jen taková jednohubka, kterou jsem dnes v zápalu boje se zkostnatělými proprietárními Unixovými systémy vyplodil. Lehce souvisí i s předchozím článkem o textových protokolech, kde popisuji všelijaké připojování na TCP porty.
Tady orel, tady orel
Ve výše zmíněném článku popisuji pozitiva nástrojů netcat a socat, které umožňují vytvoření jednoduchého socket serveru. Dnes jsem zrovna takovou funkci potřeboval, protože mým úkolem bylo nakonfigurovat novou instanci aplikačního serveru tak, aby naslouchala na předem zvoleném portu. Pracuji v prostředích s téměř paranoidní bezpečností, takže firewall je i ve vnitřních sítích samozřejmostí. Mému úkolu tedy předcházel úkol pro jiný tým, který měl zajistit, že patřičný port bude ve firewallu povolen a já mohl pokračovat pouze tehdy, až ověřím, že komunikace mezi servery skutečně funguje. Nebylo by tedy nic jednoduššího než vzít netcat a poručit mu, ať si na daný port na chvíli sedne a z druhého serveru se do něj pokusit šťouchnout. Háček je však v tom, že ve výchozí instalaci AIXu žádný netcat ani socat není. Co ale na AIXech obvykle bývá a dá se s trochu úsilí k podobné taškařici přemluvit, je Perl. Podotýkám, že tak nějak z principu se nemám rád se softwarovými technologiemi, které vznikly v dobách před mým narozením, takže kombinace AIXu a Perlu je pro mě ideálním očistcem.
Napřed jsem chvíli zápasil s funkcemi socket() a bind() a pak jsem si vzpomněl, že i přesto, že se Perlové snippety dají najít v Anthroposu mezi hroty oštěpů a Věstonickou venuší, existují v něm už i moduly a třídy nabízející přístup na vyšší úrovni. Sáhl jsem tedy po modulu IO::Socket, který mi umožnil schovat všechen ten low-level balast a vytvořit tak snadno čitelný a přenositelný skript pro primitivní socket server.
#!/usr/bin/perl -w
use IO::Socket;
$server = IO::Socket::INET->new(LocalAddr => '192.168.12.34:12345', Listen => SOMAXCONN);
die "Can't setup server" unless $server;
printf "Server started on %s port %s\n", inet_ntoa($server->sockaddr), $server->sockport;
while ($client = $server->accept()) {
printf "Connection received from %s\n", inet_ntoa($client->peeraddr);
printf $client "Welcome to %s\n", inet_ntoa($server->sockaddr);
close $client;
}