echo-server-select

システム・プログラム

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

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

■echo-server-select

HM_SubRef(tcpip-server-fork.html,echo-server-fork,echo-server-fork.c) では、クライアントから接続要求を受け付けるたびに、新しいプロセスを作っ ていた。以下の echo-server-select.cでは、1つのプロセスで実行し ている。

----------------------------------------------------------------------
:	
   2:	/*
   3:	        echo-server-select.c -- 受け取った文字列をそのまま返すサーバ(select版)
   4:	        ~yas/syspro1/ipc/echo-server-select.c
   5:	        $Header: /home/lab2/OS/yas/syspro1/ipc/RCS/echo-server-select.c,v 1.2 1998/06/15 11:37:19 yas Exp $
   6:	        Start: 1997/06/09 19:53:33
   7:	*/
   8:	#include <stdio.h>
   9:	#include <sys/types.h>  /* socket(), time(), select() */
  10:	#include <sys/socket.h> /* socket() */
  11:	#include <netinet/in.h> /* struct sockaddr_in */
  12:	#include <unistd.h>     /* select() */
  13:	#include <bstring.h>    /* select() */
  14:	#include <sys/time.h>   /* select() */
  15:	
  16:	extern  void echo_server( int portno );
  17:	extern  void echo_reply_select( int com );
  18:	extern  void print_host_port( int portno );
  19:	extern  void tcp_peeraddr_print( int com );
  20:	extern  tcp_acc_port( int portno );
  21:	extern  int writen( int fd, char *buf, int nbytes );
  22:	
  23:	main( int argc, char *argv[] )
  24:	{
  25:	    int portno ;
  26:	        if( argc >= 3 )
  27:	        {
  28:	            fprintf( stdout,"Usage: %s host port\n",argv[0] );
  29:	            exit( -1 );
  30:	        }
  31:	        if( argc == 2 )
  32:	            portno = atoi( argv[1] );
  33:	        else
  34:	            portno = getuid();
  35:	        echo_reply_select( portno );
  36:	}
  37:	
  38:	void echo_reply_select( int portno )
  39:	{
  40:	    int acc,com ;
  41:	    fd_set readfds,readfds_save ;
  42:	    int i,n ;
  43:	
  44:	        acc = tcp_acc_port( portno );
  45:	        if( acc<0 )
  46:	            exit( -1 );
  47:	        print_host_port( portno );
  48:	
  49:	        FD_ZERO( &readfds_save );
  50:	        FD_SET( acc,&readfds_save );
  51:	        while( 1 )
  52:	        {
  53:	            readfds = readfds_save ;
  54:	            n = select( FD_SETSIZE,&readfds,0,0,0 );
  55:	            if( n <= 0 )
  56:	            {
  57:	                perror("select");
  58:	                exit( 1 );
  59:	            }
  60:	            if( FD_ISSET(acc,&readfds) )
  61:	            {
  62:	                FD_CLR( acc,&readfds );
  63:	                if( (com = accept( acc,0,0 )) < 0 )
  64:	                {
  65:	                    perror("accept");
  66:	                    exit( -1 );
  67:	                }
  68:	                FD_SET( com, &readfds_save );
  69:	                tcp_peeraddr_print( com );
  70:	            }
  71:	            for( i=0 ; i<FD_SETSIZE ; i++ )
  72:	            {
  73:	                if( FD_ISSET(i,&readfds) )
  74:	                {
  75:	                    if( echo_reply_once( i )<=0 )
  76:	                    {
  77:	                        printf("[%d,%d] connection closed.\n",getpid(),i );
  78:	                        close( i );
  79:	                        FD_CLR( i,&readfds_save );
  80:	                    }
  81:	                }
  82:	            }
  83:	        }
  84:	}
  85:	
  86:	int echo_reply_once( int com )
  87:	{
  88:	    char buff[BUFSIZ] ;
  89:	    int rcount ;
  90:	    int wcount ;
  91:	
  92:	        if( (rcount=read(com,buff,BUFSIZ)) > 0 )
  93:	        {
  94:	            if( (wcount=writen(com,buff,rcount))!= rcount )
  95:	            {
  96:	                 perror("write");
  97:	                 exit( 1 );
  98:	            }
  99:	            printf("[%d,%d] ",getpid(),com );
 100:	            fflush( stdout );
 101:	            write( 1, buff, rcount );
 102:	        }
 103:	        return( rcount );
 104:	}
<以下省略>
----------------------------------------------------------------------

実行例。

サーバ側。サーバは、終了しないので、最後に、^CDel を押して、割り込みを掛けて終了させる。


----------------------------------------------------------------------
% ./echo-server-select [←]
run telnet adonis1 1231 
[1701,4] connection from 130.158.86.1:20822
[1701,4] 012
[1701,5] connection from 130.158.86.11:1479
[1701,5] abc
[1701,5] def
[1701,5] connection closed.
[1701,4] 345
[1701,4] connection closed.
^C
% []
----------------------------------------------------------------------
クライアント側(その1)。
----------------------------------------------------------------------
Trying 130.158.86.1...
Connected to adonis1.
Escape character is '^]'.
012[←]
012
345[←]
345
^]
telnet> quit[←]
Connection closed.
% []
----------------------------------------------------------------------
クライアント側(その2)。
----------------------------------------------------------------------
% telnet adonis1 1231 [←]
Trying 130.158.86.1...
Connected to adonis1.
Escape character is '^]'.
abc[←]
abc
def[←]
def
^]
telnet> quit[←]
Connection closed.
% []
----------------------------------------------------------------------

■課題提出方法


↑[もどる] ←[5月08日] ・[5月15日] [課題]
Last updated: 2000/05/14 18:57:58
Yasushi Shinjo / <yas@is.tsukuba.ac.jp>