sized_io(stream,inet)ライブラリ

システム・プログラムI

                                       電子・情報工学系
                                       新城 靖
                                       <yas@is.tsukuba.ac.jp>

このページは、次の URL にあります。
http://www.hlla.is.tsukuba.ac.jp/~yas/coins/syspro1-1998/1998-06-16 /sized_io.html
あるいは、次のページから手繰っていくこともできます。
http://www.hlla.is.tsukuba.ac.jp/~yas/coins/
http://www.hlla.is.tsukuba.ac.jp/~yas/index-j.html

■sized_ioライブラリ

sized_io ライブラリ(または、streamライブラリ)は、Don Libes 氏により開 発された、UNIX 上で TCP/IP を使うプログラムを書きやすくするためのライ ブラリである。このライブラリを使うことで、UNIX固有の繁雑なソケットを利 用することなく、もともとの TCP/IP のモデルに近い形でTCP/IPを利用するプ ログラムを書くことが可能になる。

◆initport()

stream ライブラリでは、initport() という関数が、中心的な役割を果たす。 initport() は、TCP/IP のクライアント側(接続を行う方)でも、サーバ側 (接続されるのを待つ方)でも使われる。この項では、クライアント側の使い 方を示す。

initport() は、クライアント側では、次の2種類の形式で使われる。


--------------------------------------------------------------------
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "inet.h"

int s = initport(PORT_NUMBER(port), CLIENT, SOCK_STREAM, host);
int s = initport(PORT_NAME(name), CLIENT, SOCK_STREAM, host);
int port ;
char *name ;
char *host;
--------------------------------------------------------------------

前者は、ポート番号を指定して、TCP/IP の通信路を開設するものである。重 要な引数は、サーバ側の要求受付用ポートのポート番号 port と、ホスト名 host である。その他の引数 CLIENT と SOCK_STREAM は、定数である。これら は、クライアント側で使う限り、必ず指定されなければならない。

initport() は、結果として、1つのファイル記述子 s を返す。これは、 TCP/IP の双方向ストリームに対応している。よって返されたファイル記述子 に対して次のように write() システム・コールでデータを書き込むと、その データは、接続先のプロセスに送り届けられる。

write( s, buf, size );
逆に、接続先のプロセスから送られてきたデータは、read() システム・コー ルにより受け取ることができる。
read( s, buf, size );
このように、同じファイル記述子に対して、read() と write() の両方を利用 することができる。

もう1つの形式は、ポート番号の代わりにポート名(サービス名)を指定する 方法である。たとえば、"telnet" というサービスの場合、次のようにして使 うことができる。

s = initport(PORT_NAME("telnet"), CLIENT, SOCK_STREAM, host);
この形式では、initport() は、/etc/services を参照して、与えられたポー ト名をポート番号に変換して利用する。

いずれの形式においても、エラーが生じると、initport() は、-1 を返す。

◆initport()(サーバ側)

サーバ側では、initport() は、次のような形式で使われる。

--------------------------------------------------------------------
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "inet.h"

int s = initport( PORT_NUMBER( port ), SERVER, SOCK_STREAM );

int port ;
--------------------------------------------------------------------

これにより、サーバ側に要求受付用ポートが作られる。そのポート番号は、引 数portにより指定される。initport()に対するその他の引数 (SERVER, SOCK_STREAM) は、定数である。これらは、サーバ側で使う限り、必ず指定さ れなければならない。

initport() は、結果として、1つのファイル記述子 s を返す。これは、 TCP/IP のサーバ側における要求受付用ポートと対応している。要求受付用ポー トとは、ポート番号を保持し、クライアントからの接続要求を受け付けるため のものである。このポートを通じて、データを送受することはできない。すな わち、このファイル・記述子に対して、read() システム・コールや write() システム・コールにより、入出力を行うことができない。実際に入出力を行う ためのポート(通信用ポート)は、次の select_server_stream() によって得 られる。

◆select_server_stream()(サーバ側)

select_server_stream() を使うと、自動的に接続要求を受け付けてくれ、さ れらに、入力可能なストリームを返してくれる。


--------------------------------------------------------------------
int client = select_server_stream( s, &fds );
int s ;
fd_set fds ;
--------------------------------------------------------------------

select_server_stream() の引数 s は、initport() により返されたファイル 記述子である。fdsは、select_server_stream() 内部で複数の接続扱うための 作業用変数である。fd_set とは、ファイル記述子の集合(配列)を保持する ためのビット配列である。これは、最初に FD_ZERO() により初期化されなけ ればならない。それ以後は、select_server_stream() により管理される。

select_server_stream() は、クライアントからの接続要求が来るか、クライ アントからのデータが到着するまで待つ。クライアントからの接続要求が来る と、それを受け付ける。その結果として、通信用ポートが作られる。そして、 最初のデータがクライアントから送られて来た時に、通信用ポートのファイル 記述子を返す。

select_server_stream() により返されるファイル記述子は、クライアントか らのデータが到着しており、入出力可能なTCP/IPの通信ポートに対応している。 サーバの仕事は、この通信ポートから要求を読みだし、それに応じた処理を行 い、結果をこの通信ポートに書き出すことである。

select_server_stream() は、1つのサーバ・プロセスで複数のクライアント を同時に扱う事を可能にする。サーバ・プロセスは、複数のクライアントの間 に、複数のTCP/IPの接続を同時に保持することができる。そして、それらの接 続の中で、データが届いたものを選び、返す機能がある。

なお、ネットワーク・プログラミングの教科書の多くは、ソケットを直接利用 するように書かれている。この実験においても、stream ライブラリを使うこ となく、直接ソケットを利用してプログラムを作成してもよい。

◆sized_read(),sized_write()

sized_write()とsized_read()を使うと、ストリーム(TCP/IP)上でSequenced Packets を実現することができる。ストリームでは、境界は保存されないが、 sized_write()とsized_read()を使うと、書き込み時に書いたバイト数でその まま読み出せる。

	cc = sized_read(fd,buffer,maxsize)
	cc = sized_write(fd,buffer,size)

引数は、read(),write() とよくにている。

■付録A streamライブラリ(sized_ioライブラリ)の README ファイル

--------------------------------------------------------------------

This package provides a quick-and-easy means of providing reliable
and large-packet communication between processes.

It is described further in the man page stream(3) and at length in the
document by Don Libes entitled "Packet-Oriented Communications Using a
Stream Protocol --or-- Making TCP/IP on Berkeley UNIX a Little More
Pleasant to Use", NISTIR 90-4232, January 1990.

It is especially nice because initport() does all the hard work of
initializing TCP connections, and select_server_stream() does the
hard work of connecting processes to each other.

If you are running on 4.3BSD, you should add -DBSD4_3 in the Makefile.
Otherwise, this will compile for a 4.2BSD system.

To install, type

	make install

To test, type

	make test
	reader
	writer	(in different window)
	writer  (in yet another window)
	writer  (in yet ...)
	and so on.


reader and writer are two programs that should communicate with
each other.  Type things into any of the writers and reader will
print it out prefaced by the file descriptor the data came in on.

Bugs and problems to Don Libes
National Bureau of Standards
Bldg 220, Rm A-127
Gaithersburg, MD  20899
(301) 975-3535


SYNOPSIS


#include <sys/socket.h>
#include <netinet/in.h>
#include <inet.h>

	cc [options] [files] sized_io.o stream.o

DESCRIPTION

This package implements packet or stream IO between a server process and
a number of client processes, using the TCP/IP (stream) facilities.

A client uses the call:

	s = initport(PORT_NUMBER(XXX),CLIENT,SOCK_STREAM);

s is the server's data socket and is used as a file descriptor in further
communication.  The port may be specified by name (PORT_NAME("foo")), if it
is registered.

Similarly, the server uses the following call:

	s = initport(PORT_NUMBER(XXX),SERVER,SOCK_STREAM);

s is the server's connection socket.  To receive data or connections, the
server calls select_server_stream().


	client = select_server_stream(s,&fds);


This returns a file descriptor corresponding to a client, when a client has
sent a message to the server.  It handles initial connections as well as
client deaths.  s is the server's connection socket that was returned by
initport().  fds is an int used by select...() for storing a bit string
corresponding to client sockets.  Initialize it to 0, and don't mess with it
after that.

To use the file descriptors in a stream-oriented manner, use read() and
write().  To use the file descriptors in a packet-oriented manner, use
sized_read() and sized_write().  The sized...() calls read and write one
packet at a time, while packet boundaries are ignored in read() and write().

	cc = sized_read(fd,buffer,maxsize)
	cc = sized_write(fd,buffer,size)

The arguments for sized_read() and sized_write() are very similar to read()
and write().  The only difference is that in sized_read(), maxsize is the
maximum size of an acceptable packet.
--------------------------------------------------------------------

■付録B streadm ライブラリ(sized_io ライブラリ)の入手先

streamライブラリのアーカイブ名は、sized_ioになっている。よって、archieで 文字列 sized_io を検索するとよい。

1997年6月における archie の結果:
--------------------------------------------------------------------
ftp.lab.kdd.co.jp
	/Unix
		-rw-r--r--      22851   Dec 17 1990  sized_io.shar.gz
ftp.mei.co.jp
	/free/others/Libraries
		-rw-r--r--      22851   Dec 17 1990  sized_io.shar.gz
ftp.tut.ac.jp
	/.h3/UNIX/lib
		-rw-rw-r--      22173   Jun 25 1995  sized_io.tar.gz
nadia.ics.es.osaka-u.ac.jp
	/d0/UUNET91/vol8/pub
		-rw-r--r--      34704   Jun 30 1990  sized_io.shar.Z
--------------------------------------------------------------------

↑[もどる] [課題提出方法] ←[6月9日] ・[6月16日] →[6月23日]
[sized_oi/stream/initport]
Last updated: 1998/06/15 22:32:43
Yasushi Shinjo / <yas@is.tsukuba.ac.jp>