システム・プログラム
電子・情報工学系
新城 靖
<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. %
----------------------------------------------------------------------