筑波大学 システム情報工学研究科
コンピュータサイエンス専攻, 電子・情報工学系
新城 靖
<yas@is.tsukuba.ac.jp>
このページは、次の URL にあります。
http://www.coins.tsukuba.ac.jp/~syspro/2009/No8_files/echo-server-pthread.html
あるいは、次のページから手繰っていくこともできます。
http://www.coins.tsukuba.ac.jp/~syspro/2009/
http://www.coins.tsukuba.ac.jp/~yas/
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 <stdlib.h> /* exit() */
9: #include <sys/types.h> /* socket(), time() */
10: #include <sys/socket.h> /* socket() */
11: #include <netinet/in.h> /* struct sockaddr_in */
12: #include <pthread.h> /* pthread_create */
13: #include <netdb.h> /* getnameinfo() */
14: #include <string.h> /* strlen() */
15:
16: extern void echo_server( int portno );
17: extern void echo_reply( int com );
18: extern void print_my_host_port( int portno );
19: extern void tcp_peeraddr_print( int com );
20: extern void sockaddr_print( struct sockaddr *addrp, socklen_t addr_len );
21: extern tcp_acc_port( int portno );
22: extern int fdopen_sock( int sock, FILE **inp, FILE **outp );
23:
24: main( int argc, char *argv[] )
25: {
26: int portno ;
27: if( argc != 2 )
28: {
29: fprintf( stdout,"Usage: %s portno\n",argv[0] );
30: exit( -1 );
31: }
32: portno = strtol( argv[1],0,10 );
33: echo_server( portno );
34: }
35:
main() は、
forkなし版
や
fork版
とほとんど同じである。
36: void
37: echo_server( int portno )
38: {
39: int acc,com ;
40: pthread_t worker ;
41: acc = tcp_acc_port( portno );
42: if( acc<0 )
43: exit( -1 );
44: print_my_host_port( portno );
45: while( 1 )
46: {
47: if( (com = accept( acc,0,0 )) < 0 )
48: {
49: perror("accept");
50: exit( -1 );
51: }
52: tcp_peeraddr_print( com );
53: if( pthread_create( &worker, NULL, (void *)echo_reply, (void *)com)
54: != 0 )
55: {
56: perror("pthread_create()");
57: exit( 1 );
58: }
59: pthread_detach( worker );
60: }
61: }
62:
このプログラムの特徴を以下にまとめる。
他の関数は、fork版、forkなし版とと同じである。
% diff -c echo-server-nofork-fdopen.c echo-server-pthread.c
*** echo-server-nofork-fdopen.c Mon Jun 8 18:46:58 2009
--- echo-server-pthread.c Mon Jun 8 18:53:50 2009
***************
*** 1,16 ****
/*
! echo-server-nofork-fdopen.c -- 受け取った文字列をそのまま返すサーバ(fork無し版)
! ~yas/syspro/ipc/echo-server-nofork-fdopen.c
! Created on 2004/05/09 19:08:47
*/
#include <stdio.h>
#include <stdlib.h> /* exit() */
! #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() */
#include <string.h> /* strlen() */
--- 1,15 ----
/*
! echo-server-pthread.c -- 受け取った文字列をそのまま返すサーバ(pthread版)
! ~yas/syspro/ipc/echo-server-pthread.c
! Created on 2002/02/04 21:17:04
*/
#include <stdio.h>
#include <stdlib.h> /* exit() */
! #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() */
#include <string.h> /* strlen() */
***************
*** 38,43 ****
--- 37,43 ----
echo_server( int portno )
{
int acc,com ;
+ pthread_t worker ;
acc = tcp_acc_port( portno );
if( acc<0 )
exit( -1 );
***************
*** 50,56 ****
exit( -1 );
}
tcp_peeraddr_print( com );
! echo_reply( com );
}
}
--- 50,62 ----
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
Usage: ./echo-server-pthread portno
% ./echo-server-pthread 1231
run telnet azalea20 1231
[1376] connection (fd==4) from 130.158.86.40:49838
[1376] received (fd==4) 5 bytes, [012
]
[1376] connection (fd==6) from 130.158.86.207:51885
[1376] received (fd==6) 5 bytes, [abc
]
[1376] received (fd==6) 5 bytes, [def
]
[1376] connection (fd==6) closed.
[1376] received (fd==4) 5 bytes, [345
]
[1376] connection (fd==4) closed.
^C
%
クライアント側(その1)。
% telnet azalea20 1231
Trying 130.158.86.40...
Connected to azalea20.coins.tsukuba.ac.jp.
Escape character is '^]'.
012
012
345
345
^]
telnet> ^D
Connection closed.
%
クライアント側(その2)。
% telnet azalea20 1231
Trying 130.158.86.40...
Connected to azalea20.coins.tsukuba.ac.jp.
Escape character is '^]'.
abc
abc
def
def
^]
telnet> ^D
Connection closed.
%