Mercurial > hg > y16 > e165758 > os > ex7_4
changeset 0:dc5193ff81d7
beforeFix
author | e165758 |
---|---|
date | Fri, 09 Feb 2018 14:19:11 +0900 |
parents | |
children | 32750808b041 |
files | client6.pl server6.pl |
diffstat | 2 files changed, 132 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client6.pl Fri Feb 09 14:19:11 2018 +0900 @@ -0,0 +1,45 @@ +#!/usr/bin/perl -w +# require 5.002; +use strict; +use Socket qw (getaddrinfo getnameinfo AF_UNSPEC SOCK_STREAM SOL_SOCKET SO_REUSEADDR NI_NUMERICHOST NI_NUMERICSERV ) ; +my ($remote,$port, $iaddr, $paddr, $proto, $line); + +my $user = getpwuid($<); + +$remote = shift || 'localhost'; +$port = shift || 2345; # random port +if ($port =~ /\D/) { $port = getservbyname($port, 'tcp') } +die "No port" unless $port; + +&connect_address($remote,$port); + +syswrite SOCK, "$user\n"; # or die "syswrite $!\n"; +while (<SOCK>) { + print ; +} + +close SOCK or die "close: $!"; + + +sub connect_address { + my ($host0,$port0) = @_; + + my ($err,@res) = getaddrinfo($host0, $port0, {socktype=>SOCK_STREAM}); + my $family1 = -1; + my ($err1, $host, $port); + for my $res (@res) { + my ($family, $socktype, $proto, $saddr, $canonname) = ( $res->{family} , $res->{socktype}, $res->{protocol}, $res->{addr}, $res->{canonname} ); + + ($err1, $host, $port) = getnameinfo($saddr,NI_NUMERICHOST | NI_NUMERICSERV); + print STDERR "Trying to connect to $host : $port...\n"; + + socket(SOCK, $family, $socktype, $proto) || next; + if (connect(SOCK, $saddr)) { + print STDERR "connected to $host port $port\n"; + return; + } + close(SOCK); + } + die "connect attempt failed\n"; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server6.pl Fri Feb 09 14:19:11 2018 +0900 @@ -0,0 +1,87 @@ +#!/usr/bin/perl +# require 5.002; + +use strict; +BEGIN { $ENV{PATH} = '/usr/ucb:/bin' } +use Socket qw( + getaddrinfo getnameinfo IN6ADDR_ANY AF_UNSPEC SOCK_STREAM PF_UNSPEC + AI_PASSIVE NI_NUMERICHOST NI_NUMERICSERV SOL_SOCKET SO_REUSEADDR SOMAXCONN +); + +use Carp; +use IO::Select; + +my $myself = "$0 "; +sub logmsg { print "$myself $$: @_ at ", scalar localtime, "\n" } + +my $host = shift || IN6ADDR_ANY; +my $port = shift || 2345; +my $proto = getprotobyname('tcp'); + +my $select = &bind_sockets($host,$port); + +logmsg "server started on port $port"; + +my %address_list; + +my $paddr; + +while(my @ready = $select->can_read()) { + for my $socket ( @ready ) { + my $paddr = accept(my $client, $socket); + next if (! $paddr) ; + + my ($err,$addr,$m) = getnameinfo($paddr,NI_NUMERICHOST); + my ($err,$name,$port) = getnameinfo($paddr,NI_NUMERICSERV); + $address_list{$addr} = $name; + + my $user = <$client>; + $user=~ s/[\r\n]//g; + logmsg "connection from $user \@ $name [", + $addr, "] + at port $port"; + + print $client "Hello there, $name, it's now ", + scalar localtime, "\n"; + foreach my $k (keys %address_list) { + print $client "$k = $address_list{$k}\n"; + } + close($client); + } +} + +sub bind_sockets { + my ($host0,$port0) = @_; + my $select = IO::Select->new(); + + my ($err,@res) = getaddrinfo($host0, $port0,{socktype=>SOCK_STREAM, flags=>AI_PASSIVE}); + my @socket; + my (@host); + for my $res (@res) { + my ($family, $socktype, $proto, $saddr, $canonname) = ( $res->{family} , $res->{socktype}, $res->{protocol}, $res->{addr}, $res->{canonname} ); + my ($host, $port) = getnameinfo($saddr,NI_NUMERICHOST | NI_NUMERICSERV); + print STDERR "Trying to bind to $host : $port... "; + socket(my $fd, $family, $socktype, $proto) || next; + setsockopt($fd, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) || die "setsockopt : $!"; + + if (bind($fd, $saddr)) { # sockaddr_in($port, INADDR_ANY) + listen($fd,SOMAXCONN) || die "listen: $! "; + $select->add($fd); + print STDERR "connected.\n"; + } else { + print STDERR "failed.\n"; + close($fd); + } + } + + if ($select->count == 0) { + die "connect attempt failed\n"; + } + return $select; + +} + + +sub accepts { + my ($c, @sockets) = @_; # $c is dummy +}