システム・プログラム
電子・情報工学系
新城 靖
<yas@is.tsukuba.ac.jp>
このページは、次の URL にあります。
http://www.coins.tsukuba.ac.jp/~yas/coins/syspro-2004/2004-05-10
/echo-server-pthread.html
あるいは、次のページから手繰っていくこともできます。
http://www.coins.tsukuba.ac.jp/~yas/
http://www.is.tsukuba.ac.jp/~yas/index-j.html
echo-server-pthread.cでは、プロセスではなく
スレッドを作っている。
1:
2: /*
3: echo-server-pthread.c -- 受け取った文字列をそのまま返すサーバ(pthread版)
4: ~yas/syspro/ipc/echo-server-pthread.c
5: Created on 2002/02/04 21:17:04
6: */
7: #include <stdio.h>
8: #include <sys/types.h> /* socket(), time() */
9: #include <sys/socket.h> /* socket() */
10: #include <netinet/in.h> /* struct sockaddr_in */
11: #include <pthread.h> /* pthread_create */
12: #include <netdb.h> /* getnameinfo() */
13:
14: extern void echo_server( int portno );
15: extern void echo_reply( int com );
16: extern void print_my_host_port( int portno );
17: extern void tcp_peeraddr_print( int com );
18: extern void sockaddr_print( struct sockaddr *addrp, int addr_len );
19: extern tcp_acc_port( int portno );
20: extern int fdopen_sock( int sock, FILE **inp, FILE **outp );
21:
22: main( int argc, char *argv[] )
23: {
24: int portno ;
25: if( argc >= 3 )
26: {
27: fprintf( stdout,"Usage: %s [portno] \n",argv[0] );
28: exit( -1 );
29: }
30: if( argc == 2 )
31: portno = strtol( argv[1],0,10 );
32: else
33: portno = getuid();
34: echo_server( portno );
35: }
main() 関数の部分は、fork版 とほと
んど同じである。
36:
37: void
38: echo_server( int portno )
39: {
40: int acc,com ;
41: pthread_t worker ;
42: acc = tcp_acc_port( portno );
43: if( acc<0 )
44: exit( -1 );
45: print_my_host_port( portno );
46: while( 1 )
47: {
48: if( (com = accept( acc,0,0 )) < 0 )
49: {
50: perror("accept");
51: exit( -1 );
52: }
53: tcp_peeraddr_print( com );
54: if( pthread_create( &worker, NULL, (void *)echo_reply, (void *)com)
55: != 0 )
56: {
57: perror("pthread_create()");
58: exit( 1 );
59: }
60: pthread_detach( worker );
61: }
62: }
63:
このプログラムの特徴を以下にまとめる。
他の関数は、fork版と同じである。
% diff -c echo-server-nofork-fdopen.c echo-server-pthread.c
echo-server-nofork-fdopen.c Sun May 9 23:19:57 2004
--- echo-server-pthread.c Sun May 9 23:19:53 2004
1,16 ****
/*
! echo-server-nofork-fdopen.c -- 受け取った文字列をそのまま返すサーバ(fork無し版)
! ~yas/syspro/ipc/echo-server-nofork-fdopen.c
! Created on 2004/05/09 19:08:47
*/
- #define _USE_BSD /* wait4() */
#include <stdio.h>
! #include <sys/types.h> /* socket(), wait4() */
#include <sys/socket.h> /* socket() */
#include <netinet/in.h> /* struct sockaddr_in */
! #include <sys/resource.h> /* wait4() */
! #include <sys/wait.h> /* wait4() */
#include <netdb.h> /* getnameinfo() */
extern void echo_server( int portno );
--- 1,14 ----
/*
! echo-server-pthread.c -- 受け取った文字列をそのまま返すサーバ(pthread版)
! ~yas/syspro/ipc/echo-server-pthread.c
! Created on 2002/02/04 21:17:04
*/
#include <stdio.h>
! #include <sys/types.h> /* socket(), time() */
#include <sys/socket.h> /* socket() */
#include <netinet/in.h> /* struct sockaddr_in */
! #include <pthread.h> /* pthread_create */
#include <netdb.h> /* getnameinfo() */
extern void echo_server( int portno );
40,45 ****
--- 38,44 ----
echo_server( int portno )
{
int acc,com ;
+ pthread_t worker ;
acc = tcp_acc_port( portno );
if( acc<0 )
exit( -1 );
52,58 ****
exit( -1 );
}
tcp_peeraddr_print( com );
! echo_reply( com );
}
}
--- 51,63 ----
exit( -1 );
}
tcp_peeraddr_print( com );
! if( pthread_create( &worker, NULL, (void *)echo_reply, (void *)com)
! != 0 )
! {
! perror("pthread_create()");
! exit( 1 );
! }
! pthread_detach( worker );
}
}
%
実行例。
サーバ側。サーバは、終了しないので、最後に、^C を押して、割り 込みを掛けて終了させる。
注意:全員がポート番号 1231 を使うとプログラムが動かないことがある。
---------------------------------------------------------------------- % ./echo-server-pthread 1231クライアント側(その1)。run telnet adonis9.coins.tsukuba.ac.jp 1231 [7298] connection (fd==4) from 130.158.86.28:47333 [7300] received (fd==4) 5 bytes, [012 ] [7298] connection (fd==8) from 127.0.0.1:42170 [7302] received (fd==8) 5 bytes, [abc ] [7302] received (fd==8) 5 bytes, [def ] [7302] connection (fd==8) closed. [7300] received (fd==4) 5 bytes, [345 ] [7300] connection (fd==4) closed. ^C %
----------------------------------------------------------------------
---------------------------------------------------------------------- % telnet adonis9.coins.tsukuba.ac.jp 1231クライアント側(その2)。Trying 130.158.86.29... Connected to adonis9.coins.tsukuba.ac.jp. Escape character is '^]'. 012
012 345
345 ^] telnet> quit
Connection closed. %
----------------------------------------------------------------------
---------------------------------------------------------------------- % telnet adonis9.coins.tsukuba.ac.jp 1231Trying 130.158.86.29... Connected to adonis9.coins.tsukuba.ac.jp. Escape character is '^]'. abc
abc def
def ^] telnet> quit
Connection closed. %
----------------------------------------------------------------------