Operating System Lecture 9/5

Operating System Lecture 9/5

Interprocess Communication

Unix では、ネットワークプログラミングには socket を使う。socket は、ファイルディスクプタである。つまり、 ユーザからは普通のファイルと同様にread/writeすることができる。 しかし、ファイルの名前等はない。

Networkは、階層構造になっていて、その様々な部分でOSが関与することに なる。



実際のUnix のネットワークプログラミングでは、ホスト内部ではファイル名を アドレスに使うUnix domainと、32bit のアドレスを使うTCP/IPが主流である。 その中で、さらに、connection less のUDPと、stream connectionのTCPとに 分かれる。



        #!/usr/bin/perl -w
         use strict;
         require 5.002;
         use Socket;
         use Sys::Hostname;

         my ( $count, $hisiaddr, $hispaddr, $histime,
              $host, $iaddr, $paddr, $port, $proto,
              $rin, $rout, $rtime, $SECS_of_70_YEARS);

         $SECS_of_70_YEARS      = 2208988800;

         $iaddr = gethostbyname(hostname());
         $proto = getprotobyname('udp');
         $port = getservbyname('time', 'udp');
         $paddr = sockaddr_in(0, $iaddr); # 0 means let kernel pick

         socket(SOCKET, PF_INET, SOCK_DGRAM, $proto)   || die "socket: $!";
         bind(SOCKET, $paddr)                          || die "bind: $!";

         $| = 1;
         printf "%-12s %8s %s\n",  "localhost", 0, scalar localtime time;
         $count = 0;
         for $host (@ARGV) {
             $count++;
             $hisiaddr = inet_aton($host)    || die "unknown host";
             $hispaddr = sockaddr_in($port, $hisiaddr);
            defined(send(SOCKET, 0, 0, $hispaddr))    || die "send $host: $!";
         }

         $rin = '';
         vec($rin, fileno(SOCKET), 1) = 1;

         # timeout after 10.0 seconds
         while ($count && select($rout = $rin, undef, undef, 10.0)) {
             $rtime = '';
             ($hispaddr = recv(SOCKET, $rtime, 4, 0))        || die "recv: $!";
             ($port, $hisiaddr) = sockaddr_in($hispaddr);
             $host = gethostbyaddr($hisiaddr, AF_INET);
             $histime = unpack("N", $rtime) - $SECS_of_70_YEARS ;
             printf "%-12s ", $host;
             printf "%8d %s\n", $histime - time, scalar localtime($histime);
             $count--;
         }


TCPでは、1対1でつなげるよりも、 Unixではdaemonと呼ばれる Clinet / Server モデルを構成する ことが多い。



     #!/usr/bin/perl -w
         require 5.002;
         use strict;
         use Socket;
         my ($remote,$port, $iaddr, $paddr, $proto, $line);

         $remote  = shift || 'localhost';
         $port    = shift || 2345;  # random port
         if ($port =~ /\D/) { $port = getservbyname($port, 'tcp') }
         die "No port" unless $port;
         $iaddr   = inet_aton($remote)               || die "no host: $remote";
         $paddr   = sockaddr_in($port, $iaddr);

         $proto   = getprotobyname('tcp');
         socket(SOCK, PF_INET, SOCK_STREAM, $proto)  || die "socket: $!";
         connect(SOCK, $paddr)    || die "connect: $!";
         while (defined($line = )) {
             print $line;
         }

         close (SOCK)            || die "close: $!";
         exit;
      #!/usr/bin/perl -Tw
         require 5.002;
         use strict;
         BEGIN { $ENV{PATH} = '/usr/ucb:/bin' }
         use Socket;
         use Carp;

         sub logmsg { print "$0 $$: @_ at ", scalar localtime, "\n" }

         my $port = shift || 2345;
         my $proto = getprotobyname('tcp');
         $port = $1 if $port =~ /(\d+)/; # untaint port number

         socket(Server, PF_INET, SOCK_STREAM, $proto)        || die "socket: $!"
;
         setsockopt(Server, SOL_SOCKET, SO_REUSEADDR,
                                             pack("l", 1))   || die "setsockopt:
 $!";
         bind(Server, sockaddr_in($port, INADDR_ANY))        || die "bind: $!";
         listen(Server,SOMAXCONN)                            || die "listen: $!"
;

       logmsg "server started on port $port";

         my $paddr;

         $SIG{CHLD} = \&REAPER;

         for ( ; $paddr = accept(Client,Server); close Client) {
             my($port,$iaddr) = sockaddr_in($paddr);
             my $name = gethostbyaddr($iaddr,AF_INET);

             logmsg "connection from $name [",
                     inet_ntoa($iaddr), "]
                     at port $port";

             print Client "Hello there, $name, it's now ",
                             scalar localtime, "\n";
         }


Unix ネットワークの用語



その他のInterprocess Communication