# Copyright (c) 1997-2005
# Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
# http://www.math.tu-berlin.de/polymake, mailto:polymake@math.tu-berlin.de
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version: http://www.gnu.org/licenses/gpl.txt.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#-----------------------------------------------------------------------------
# $Project: polymake $$Id: Sockets.pm 6648 2005-12-21 19:18:10Z gawrilow $
use strict;
use namespaces;
package Poly::ServerSocket;
use Poly::Pipe;
use Socket;
use Errno;
use Fcntl;
use POSIX qw(:errno_h);
use Struct (
[ new => ';$' ],
[ '$handle' => 'undef' ],
[ '$port' => '#1' ],
);
# Constructor: new ServerSocket([ port ])
sub new {
my $self=&_new;
socket $self->handle, PF_INET, SOCK_STREAM, getprotobyname('tcp')
or die "socket failed: $!\n";
fcntl $self->handle, F_SETFD, 0 # keep opened in the client
or die "fcntl(F_SETFD) failed: $!\n";
if (defined $self->port) {
bind $self->handle, sockaddr_in($self->port, INADDR_LOOPBACK)
or die "bind failed: $!\n";
} else {
my $port;
for ($port=30000; $port<65536; ++$port) {
last if bind $self->handle, sockaddr_in($port, INADDR_LOOPBACK);
die "bind failed: $!\n" if $! != EADDRINUSE;
}
if ($port==65536) {
die "bind failed: all ports seem occupied\n";
}
$self->port=$port;
}
listen $self->handle, 1
or die "listen failed: $!\n";
$self;
}
sub DESTROY {
close($_[0]->handle);
}
sub fileno { fileno($_[0]->handle) }
sub accept {
my ($self)=@_;
accept my $s, $self->handle
or die "accept failed: $!\n";
new Pipe($s);
}
####################################################################################
package Poly::ClientSocket;
use Socket;
# Constructor: new ClientSocket(hostname, port)
sub new {
my ($class, $hostname, $port)=@_;
my $hostaddr=inet_aton($hostname)
or die "unknown host name $hostname\n";
socket(my $socket, PF_INET, SOCK_STREAM, getprotobyname('tcp'))
or die "can't create socket: $!\n";
connect($socket, sockaddr_in($port, $hostaddr))
or die "can't connect to $hostname: $!\n";
new Pipe($socket);
}
1
syntax highlighted by Code2HTML, v. 0.9.1