# 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