システム・プログラム 電子・情報工学系 新城 靖 <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.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: } <以下省略> ----------------------------------------------------------------------実行例。
サーバ側。サーバは、終了しないので、最後に、^C か Del を押して、割り込みを掛けて終了させる。
クライアント側(その1)。---------------------------------------------------------------------- % ./echo-server-selectrun 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 %
----------------------------------------------------------------------
クライアント側(その2)。---------------------------------------------------------------------- Trying 130.158.86.1... Connected to adonis1. Escape character is '^]'. 012012 345
345 ^] telnet> quit
Connection closed. %
----------------------------------------------------------------------
---------------------------------------------------------------------- % telnet adonis1 1231Trying 130.158.86.1... Connected to adonis1. Escape character is '^]'. abc
abc def
def ^] telnet> quit
Connection closed. %
----------------------------------------------------------------------