情報学類 分散システム 2008年12月16日 筑波大学システム情報工学研究科 コンピュータサイエンス専攻, 電子・情報工学系 新城 靖 <yas@is.tsukuba.ac.jp>
このページは、次の URL にあります。
http://www.coins.tsukuba.ac.jp/~yas/coins/dsys-2008/2008-12-16
あるいは、次のページから手繰っていくこともできます。
http://www.coins.tsukuba.ac.jp/~yas/
http://www.cs.tsukuba.ac.jp/~yas/
main() { connect(); // 結合が作られる通信プリミティブを使う時 marshal(); send(); receive(); unmarshal(); close(); // 結合が作られる通信プリミティブを使う時 }
main() make_port(); // 結合が作られる通信プリミティブを使う時 while( 1 ) { accept(); // 結合が作られる通信プリミティブを使う時 receive(); unmarshal(); 仕事(); marshal(); send(); close(); // 結合が作られる通信プリミティブを使う時 } }marshaling のことを Java 用語では、serialize という。
今後 TCP/IP 以外にも様々な通信プロトコルが開発され、Unix で利用できる ように設計されている。TCP/IP で使う時には、煩雑である。
int socket = socket(int domain, int type, int protocol)主に domain と type で利用するプロトコルを指定する。 最後の引数 protocol は、普段は 0 を指定する。
ドメイン(domain) | 型(type) | プロトコル(protocol) |
PF_INET | SOCK_STREAM | TCP(IPv4) |
PF_INET | SOCK_DGRAM | UDP(IPv4) |
PF_INET6 | SOCK_STREAM | TCP(IPv6) |
PF_INET6 | SOCK_DGRAM | UDP(IPv6) |
PF_UNIX | SOCK_STREAM | 同一ホスト内(UNIXドメイン)のストリーム |
PF_UNIX | SOCK_DGRAM | 同一ホスト内(UNIXドメイン)のデータグラム |
PF_NS | SOCK_STREAM | XNS のストリーム(SPP) |
PF_NS | SOCK_SEQPACKET | XNS の順序付きパケット(IDP) |
PF_NS | SOCK_RDM | XNSの信頼性のあるデータグラム(SPP) |
名前 | 説明 |
socket() | 通信プロトコルに対応したソケット・オブジェクトを作成する |
connect() | 結合(conection)を確立させる。サーバのアドレスを固定する。 |
listen() | サーバ側で接続要求の待ち受けを開始する。 |
accept() | サーバ側で接続されたソケットを得る。 |
bind() | ソケットにアドレス(名前)を付ける。 |
getpeername() | 通信相手のアドレス(名前)を得る。 |
getsockname() | 自分のアドレス(名前)を得る。 |
send(), sendto(), sendmsg() | メッセージを送信する。 |
recv(), recvfrom(), recvmsg() | メッセージを受信する。 |
shutdown() | 双方向の結合を部分的に切断する。 |
getsockopt() | オプションの現在の値を取得する。 |
setsockopt() | オプションを設定する。 |
select(), poll() | 複数の入出力(通信を含む)を多重化する。 |
write() | メッセージを送信する。 |
read() | メッセージを受信する。 |
close() | ファイル記述子を閉じる。他に参照しているファイル記述子がなければ、ソケット・オブジェクトを削除する。 |
名前 | 説明 |
gethostbyname() | ホスト名から IP アドレスを調べる。 |
getaddrinfo() | ホスト名から IP アドレスを調べる。IPv6対応。 |
gethostbyaddr() | IPアドレスからホスト名を調べる。 |
getnameinfo() | IPアドレスからホスト名を調べる。IPv6対応。 |
freeaddrinfo() | getaddrinfo(), getnameinfo() で得られた構造体を解放する。 |
tcp_acc_port( int portno )
(サーバ側)
int tcp_connect( char *server, int portno )
(クライアント側)
accept()
をそのまま使う。
accept()
は、1つのクライアントから接続要求を受け付ける。
第1引数の socket は、tcp_acc_port() で作成したソケットを渡す。
TCP/IP では、クラ イアント側とサーバ側でソケット・オブジェクトの作成するクラスが違ってい る。
クラス名 | 説明 |
---|---|
Socket | TCP/IP のクライアント側のソケット |
ServerSocket | TCP/IP のサーバ側のソケット |
DatagramSocket | UDP/IP のソケット |
以後、ネットワークか ら文字列を入力するには、InputStreamReader や BufferedReader のオブジェ クトを生成して利用する。
出力側では、Socket クラスのオブジェクトに対して getOutputStream() して、 OutputStream クラスのオブジェクトを得て、 PrintStream オブジェクトを生成して利用できる。
図? ネットワークOSでのアプリケーションの実行
ライブラリの機能。クライアントとして働く。 サーバは、サーバ server のポート番号 portno で動作している。get_highscore_client(char *server, int portno, score_record_t records[], int len )
score_record_t
型)を最大 len
個だけ取得する。
実際に保存していた数を返す。
int put_score_client(char *server, int portno, int score, char *user)
.
」を忘れないように。
% mkdir hiscore-tcp
% cd hiscore-tcp
% cp ~yas/dsys/highscore/tcp/add-hiscore.c .
% cp ~yas/dsys/highscore/tcp/highscore-client.c .
% cp ~yas/dsys/highscore/tcp/highscore-server.c .
% cp ~yas/dsys/highscore/tcp/highscore-tcp.h .
% cp ~yas/dsys/highscore/tcp/marshaling-burffer.c .
% cp ~yas/dsys/highscore/tcp/marshaling-burffer.h .
% cp ~yas/dsys/highscore/tcp/show-hiscore.c .
% cp ~yas/dsys/highscore/tcp/Makefile .
% ls
Makefile highscore-server.c marshaling-burffer.h
add-hiscore.c highscore-tcp.h show-hiscore.c
highscore-client.c marshaling-burffer.c
%
% make
cc -g -c -o add-hiscore.o add-hiscore.c
cc -g -c -o highscore-client.o highscore-client.c
cc -g -c -o marshaling-burffer.o marshaling-burffer.c
cc -g add-hiscore.o highscore-client.o marshaling-burffer.o -o add-hiscore
cc -g -c -o show-hiscore.o show-hiscore.c
cc -g show-hiscore.o highscore-client.o marshaling-burffer.o -o show-hiscore
cc -g -c -o highscore-server.o highscore-server.c
cc -g highscore-server.o marshaling-burffer.o -o highscore-server
% ls
Makefile highscore-server marshaling-burffer.o
add-hiscore highscore-server.c show-hiscore
add-hiscore.c highscore-server.o show-hiscore.c
add-hiscore.o highscore-tcp.h show-hiscore.o
highscore-client.c marshaling-burffer.c
highscore-client.o marshaling-burffer.h
%
make
コマンドを実行すると、Makefile
の記述に従い3つの実行
形式のファイル highscore-server
,
add-hiscore
, add-hiscore
が作られる。
例題を実行するには、クライアント用とサーバ用に端末を2つ開く。
その方法は、make help
で表示される。
% make help
Open two terminals for server and client
server:
./highscore-server portno
(To stop this server, Press ^C)
client:
./add-hiscore server portno score name
./show-hiscore server portno num
%
クライアントとサーバは、別のコンピュータで動作させても良い。 以下の例では、サーバをazalea20 で動作させている。 サーバ側:
% ssh azalea20
% cd hiscore-tcp/
% ./highscore-server
Usage: % ./highscore-server portno
% ./highscore-server 1231
run client azalea20 1231
(To stop this server, Press ^C)
サーバは終了しないので、実験が終わったら ^C で止める。
クライアント側は、もう1つの端末で実行する。
% ./add-hiscore
Usage: % ./add-hiscore server portno score "User Name"
% ./add-hiscore azalea20 1231 10 "Yasushi Shinjo"
% ./add-hiscore azalea20 1231 20 "Kazuhiko Kato"
% ./show-hiscore
Usage: % ./show-hiscore host portno n
% ./show-hiscore azalea20 1231 10
2 hiscore record(s) received
20 Kazuhiko Kato
10 Yasushi Shinjo
%
実験が終了したら、サーバを ^C コマンドで削除する。
% ./highscore-server 1231
run client azalea20 1231
(To stop this server, Press ^C)
[11418] connection (fd==4) from 130.158.86.207:60898
[11418] connection (fd==4) from 130.158.86.207:60900
[11418] connection (fd==4) from 130.158.86.207:60903
^C
%
図? クライアント・サーバ間で交わされる要求メッセージと応答メッセージ
hiscoreで用いる要求メッセージの形式図? 要求メッセージの例
図? 応答メッセージの例
1: 2: /* 3: highscore-tcp.h -- Hiscore Protocol over TCP 4: Created on: 2008/12/05 19:06:01 5: ~/dsys/highscore/tcp/highscore-proto.h 6: */ 7: 8: #ifndef _HIGHSCORE_TCP_H_ 9: #define _HIGHSCORE_TCP_H_ 10: 11: #define HISCORE_PROTO_MAX_MESSAGE_SIZE 1024 12: 13: #define HISCORE_PROTO_GET_HISCORE 1 14: #define HISCORE_PROTO_PUT_SCORE 2 15: 16: #define HISCORE_PROTO_OK 0 17: #define HISCORE_PROTO_NO_COMMAND -1 18: #define HISCORE_PROTO_MARSHAL_ERROR -2 19: 20: #define HIGHSCORE_MAX_RECORDS 10 21: #define HIGHSCORE_NAME_LEN 28 22: 23: struct score_record { 24: int score; 25: char name[HIGHSCORE_NAME_LEN]; 26: }; 27: typedef struct score_record score_record_t; 28: 29: /* for clients */ 30: extern int get_highscore_client(char *server, int portno, 31: score_record_t records[], int len ); 32: extern int put_score_client(char *server, int portno, int score, char *user); 33: 34: #endif _HIGHSCORE_TCP_H_
score_record_t
で表現する。
この構造体は、全体で32バイトある。の最初の4バイトは、整数型で、得点、残
りの28バイトは、文字の配列。ASCII で最大27文字まで保存できる。文字が含
まれない部分は、0が入る。
score_record_t
型の配列で表す。
get_highscore_client()
と
put_score_client
がある。
図?モジュールの構成
int marbuf_init( marbuf_t *mb, size_t len )
void marbuf_final( marbuf_t *mb )
int marbuf_receive_message( marbuf_t *mb, int socket )
int marbuf_send_message( marbuf_t *mb, int socket )
int marbuf_marshal_int( marbuf_t *mb, int data )
int marbuf_unmarshal_int( marbuf_t *mb, int *datap )
int marbuf_marshal_byte_array( marbuf_t *mb, char data[], int data_len )
int marbuf_unmarshal_byte_array( marbuf_t *mb, char data[], int data_len )
marbuf_t message; int x; marbuf_init( &message, MAX_MESSAGE_SIZE ); marbuf_marshal_int( &message, x ); marbuf_send_message( &message, socket ); marbuf_final( &message, socket );基本的な使い方: メッセージの受信とアンマーシャリング
marbuf_t message; int x; marbuf_init( &message, MAX_MESSAGE_SIZE ); marbuf_receive_message( &message, socket ); marbuf_unmarshal_int( &message, &x ); marbuf_final( &message, socket );
put_score_client()
関数を呼び出す簡単なプログラム。
1: 2: /* 3: add-hiscore.c -- The main function of put_score_client(). 4: Created on: 2008/12/06 17:47:08 5: ~yas/dsys/highscore/tcp/add-hiscore.c 6: */ 7: 8: #include <stdio.h> /* stderr, fprintf() */ 9: #include <stdlib.h> /* strtol() */ 10: #include "highscore-tcp.h" 11: 12: void usage( char *comname ) { 13: fprintf(stderr,"Usage: %% %s server portno score \"User Name\"\n", comname); 14: exit( 1 ); 15: } 16: 17: main( int argc, char *argv[], char *envp[] ) { 18: int score, portno ; 19: char *name, *server ; 20: if( argc != 5 ) 21: usage( argv[0] ); 22: server = argv[1]; 23: portno = strtol( argv[2], 0, 10); 24: score = strtol( argv[3], 0, 10); 25: name = argv[4]; 26: put_score_client( server, portno, score, name ); 27: }
put_score_client()
関数を呼び出す。
get_hiscore_client()
関数を呼び出す簡単なプログラム。
1: 2: /* 3: show-hiscore.c -- The main function for get_highscore_client(). 4: Created on: 2008/12/06 19:21:52 5: ~yas/dsys/highscore/centralized/show-hiscore.c 6: */ 7: 8: #include <stdio.h> /* stderr, fprintf() */ 9: #include <stdlib.h> /* strtol() */ 10: #include "highscore-tcp.h" 11: 12: static void show_score( char *host, int port, int top ); 13: 14: static void usage( char *comname ) { 15: fprintf(stderr,"Usage: %% %s host portno n\n", comname); 16: exit( 1 ); 17: } 18: 19: main( int argc, char *argv[], char *envp[] ) { 20: int top, portno ; 21: char *name, *server ; 22: if( argc != 4 ) 23: usage( argv[0] ); 24: server = argv[1]; 25: portno = strtol( argv[2], 0, 10); 26: top = strtol( argv[3], 0, 10); 27: show_score( server, portno, top ); 28: } 29: 30: static void show_score( char *server, int portno, int top ) { 31: score_record_t records[HIGHSCORE_MAX_RECORDS]; 32: int n, i ; 33: if( top > HIGHSCORE_MAX_RECORDS ) { 34: fprintf(stderr,"Warning: top too large: %d\n",top); 35: top = HIGHSCORE_MAX_RECORDS; 36: } 37: n = get_highscore_client( server, portno, records, top ); 38: if( n >= 0 ) { 39: printf("%d hiscore record(s) received\n", n ); 40: for( i=0; i<n; i++ ) { 41: printf("%10d %s\n", records[i].score, records[i].name ); 42: } 43: } 44: else { 45: printf("error: %d\n", n ); 46: } 47: }
put_score_client()
関数を呼び出す。
1: 2: /* 3: highscore-client.c -- The hiscore client using TCP/IP stream. 4: Created on: 2008/12/06 17:03:28 5: ~yas/dsys/highscore/tcp/highscore-client.c 6: */ 7: 8: #include <stdio.h> /* stderr, fprintf() */ 9: #include <stdlib.h> /* strtol() */ 10: #include <string.h> /* memcpy() */ 11: #include <sys/types.h> /* socket() */ 12: #include <sys/socket.h> /* socket() */ 13: #include <netinet/in.h> /* struct sockaddr_in */ 14: #include <netdb.h> /* getaddrinfo(), freeaddrinfo(), struct addrinfo */ 15: #include "highscore-tcp.h" 16: #include "marshaling-burffer.h" 17: 18: /* From Coins System Program */ 19: extern int tcp_connect( char *server, int portno ); 20: extern int sockaddr_in_init( struct sockaddr_in *addr, int addrlen, 21: char *hostname, int portno ); 22:
tcp_connect()
と sockaddr_in_init()
を使う。
23: int get_highscore_client( char *server, int portno, 24: score_record_t records[], int len ) { 25: int sock, cmd, n, i; 26: marbuf_t request, reply; 27: marbuf_init( &request,HISCORE_PROTO_MAX_MESSAGE_SIZE ); 28: marbuf_init( &reply,HISCORE_PROTO_MAX_MESSAGE_SIZE ); 29: if( !marbuf_marshal_int( &request, HISCORE_PROTO_GET_HISCORE ) ) 30: goto error0; 31: marbuf_marshal_int( &request, len ); 32: if( (sock = tcp_connect( server, portno )) < 0 ) { 33: perror("tcp_sonnect"); 34: goto error0; 35: } 36: if( marbuf_send_message( &request, sock ) < 0 ) { 37: perror("send"); 38: goto error1; 39: } 40: if( marbuf_receive_message( &reply, sock ) < 0 ) { 41: perror("recieve"); 42: goto error1; 43: } 44: if( !marbuf_unmarshal_int( &reply, &n ) ) { 45: fprintf(stderr,"unmarshal n\n"); 46: goto error1; 47: } 48: if( n > len ) { 49: fprintf(stderr,"received message too large: %d > %d\n", n, len ); 50: goto error1; 51: } 52: for( i=0 ; i<n; i++ ) { 53: if( !marbuf_unmarshal_int(&reply,&records[i].score ) ) { 54: fprintf(stderr,"unmarshal name\n"); 55: goto error1; 56: } 57: if( !marbuf_unmarshal_byte_array(&reply,records[i].name, 58: HIGHSCORE_NAME_LEN) ) { 59: fprintf(stderr,"unmarshal name\n"); 60: goto error1; 61: } 62: } 63: close( sock ); 64: marbuf_final( &request ); 65: marbuf_final( &reply ); 66: return( n ); 67: 68: error1: close( sock ); 69: error0: marbuf_final( &request ); 70: marbuf_final( &reply ); 71: return( -1 ); 72: } 73:
74: int put_score_client(char *server, int portno, int score, char *name) { 75: int sock, cmd, ok; 76: marbuf_t request, reply; 77: char name_buf[HIGHSCORE_NAME_LEN]; 78: marbuf_init( &request,HISCORE_PROTO_MAX_MESSAGE_SIZE ); 79: marbuf_init( &reply,HISCORE_PROTO_MAX_MESSAGE_SIZE ); 80: if( !marbuf_marshal_int( &request, HISCORE_PROTO_PUT_SCORE) ) 81: goto error0; 82: if( !marbuf_marshal_int( &request, score ) ) 83: goto error0; 84: memset( name_buf, 0, HIGHSCORE_NAME_LEN ); 85: snprintf( name_buf, HIGHSCORE_NAME_LEN, "%s", name ); 86: if( !marbuf_marshal_byte_array( &request, name_buf, HIGHSCORE_NAME_LEN ) ) 87: goto error0; 88: if( (sock = tcp_connect( server, portno )) < 0 ) { 89: perror("tcp_sonnect"); 90: goto error0; 91: } 92: if( marbuf_send_message( &request, sock ) < 0 ) { 93: perror("send"); 94: goto error1; 95: } 96: if( marbuf_receive_message( &reply, sock ) < 0 ) { 97: perror("recieve"); 98: goto error1; 99: } 100: if( !marbuf_unmarshal_int( &reply, &ok ) ) { 101: fprintf(stderr,"unmarshal n\n"); 102: goto error1; 103: } 104: close( sock ); 105: marbuf_final( &request ); 106: marbuf_final( &reply ); 107: return( ok ); 108: 109: error1: close( sock ); 110: error0: marbuf_final( &request ); 111: marbuf_final( &reply ); 112: return( -1 ); 113: } 114:
115: /* From Coins System Program */ 116: int tcp_connect( char *server, int portno ) { ... 136: int sockaddr_in_init( struct sockaddr_in *addr, int addrlen, 137: char *hostname, int portno ) { ...
1: 2: /* 3: highscore-server.c -- The hiscore server using TCP/IP stream. 4: Created on: 2008/12/05 18:56:11 5: ~yas/dsys/highscore/tcp/highscore-server.c 6: */ 7: 8: #include <stdio.h> /* stderr, fprintf() */ 9: #include <stdlib.h> /* strtol() */ 10: #include <string.h> /* memcpy() */ 11: #include <sys/types.h> /* socket() */ 12: #include <sys/socket.h> /* socket() */ 13: #include <netinet/in.h> /* struct sockaddr_in, INADDR_ANY */ 14: #include <netdb.h> /* getnameinfo() */ 15: #include "highscore-tcp.h" 16: #include "marshaling-burffer.h" 17: 18: /* From Coins System Program */ 19: extern int tcp_acc_port( int portno ); 20: extern void tcp_peeraddr_print( int com ); 21: extern void sockaddr_print( struct sockaddr *addrp, socklen_t addr_len ); 22: extern int tcp_acc_port( int portno ); 23: 24: /* Hiscore data in memory */ 25: static score_record_t hiscore_records[HIGHSCORE_MAX_RECORDS]; 26: static int hiscore_nelements; 27: 28: static void hiscore_server( int portno ); 29: static void hiscore_request_reply( int com ); 30: static void print_my_host_port( int portno ); 31: static int insert_score( score_record_t records[], int len, int nelement, 32: int score, char *user ); 33: static int find_posision( score_record_t records[], int len, int nelement, 34: int score ); 35: 36: static void usage( char *comname ) { 37: fprintf(stderr,"Usage: %% %s portno\n", comname); 38: exit( 1 ); 39: } 40: 41: main( int argc, char *argv[], char *envp[] ) { 42: int portno; 43: if( argc != 2 ) 44: usage( argv[0] ); 45: portno = strtol( argv[1], 0, 10 ); 46: hiscore_server( portno ); 47: } 48:
tcp_acc_port()
, tcp_peeraddr_print()
,
sockaddr_print()
を使う。
hiscore_records[]
にハイスコアのデータを保持する。
その要素数は、hiscore_nelements
に保持する。
main()
は、文字列でポート番号を引数にとり、それを整数にして
hiscore_server()
を呼び出す。
49: static void hiscore_server( int portno ) { 50: int acc,com ; 51: acc = tcp_acc_port( portno ); 52: if( acc<0 ) 53: exit( -1 ); 54: print_my_host_port( portno ); 55: printf("(To stop this server, Press ^C)\n"); 56: while( 1 ) { 57: if( (com = accept( acc,0,0 )) < 0 ) { 58: perror("accept"); 59: exit( -1 ); 60: } 61: tcp_peeraddr_print( com ); 62: hiscore_request_reply( com ); 63: } 64: } 65:
tcp_acc_port()
で、接続受付の準備をする。
accept()
で、1つのクライアントから接続を受け付ける。
hiscore_request_reply()
で、要求の受信と応答の送信を行う。
66: static void hiscore_request_reply( int com ) { 67: marbuf_t request, reply; 68: int cmd; 69: marbuf_init( &request,HISCORE_PROTO_MAX_MESSAGE_SIZE ); 70: marbuf_init( &reply,HISCORE_PROTO_MAX_MESSAGE_SIZE ); 71: if( marbuf_receive_message( &request, com ) < 0 ) { 72: perror("read"); 73: goto error0; 74: } 75: 76: if( !marbuf_unmarshal_int( &request, &cmd ) ) { 77: perror("request_msg cmd"); 78: goto error0; 79: } 80: switch( cmd ) { 81: case HISCORE_PROTO_PUT_SCORE: 82: { 83: int score ; char name[HIGHSCORE_NAME_LEN]; 84: if( !marbuf_unmarshal_int( &request, &score ) ) 85: goto error1; 86: if( !marbuf_unmarshal_byte_array( &request, name, HIGHSCORE_NAME_LEN ) ) 87: goto error1; 88: hiscore_nelements = insert_score( hiscore_records, HIGHSCORE_MAX_RECORDS, 89: hiscore_nelements, score, name ); 90: if( !marbuf_marshal_int( &reply, HISCORE_PROTO_OK ) ) 91: goto error1; 92: break; 93: } 94: case HISCORE_PROTO_GET_HISCORE: 95: { 96: int len,i,n ; 97: if( !marbuf_unmarshal_int( &request, &len ) ) 98: goto error1; 99: if( len > HIGHSCORE_MAX_RECORDS ) 100: len = HIGHSCORE_MAX_RECORDS; 101: n = len < hiscore_nelements ? len : hiscore_nelements ; 102: /* return n and hiscore_records[0..n-1] to client. */ 103: if( !marbuf_marshal_int( &reply, n ) ) 104: goto error1; 105: for( i=0 ; i<n; i++ ) 106: { 107: if( !marbuf_marshal_int( &reply,hiscore_records[i].score ) ) 108: goto error1; 109: if( !marbuf_marshal_byte_array( 110: &reply,hiscore_records[i].name,HIGHSCORE_NAME_LEN ) ) 111: goto error1; 112: } 113: break; 114: } 115: default: 116: marbuf_marshal_int( &reply, HISCORE_PROTO_NO_COMMAND ); 117: break; 118: } 119: marbuf_send_message( &reply, com ); 120: 121: error0: marbuf_final( &request ); 122: marbuf_final( &reply ); 123: close( com ); 124: return; 125: 126: error1: marbuf_marshal_int( &reply, HISCORE_PROTO_MARSHAL_ERROR ); 127: marbuf_send_message( &reply, com ); 128: goto error0; 129: } 130:
marbuf_receive_message()
で、要求メッセージを受信する。
cmd
にコマンドに(整数型)を1つ取出す。
cmd
が PUT_SCORE の場合、
cmd
が GET_HISCORE の場合、
hiscore_records[]
のi番目の要素を応答メッ
セージに加える。
hiscore_records[]
の
i番目の要素のスコアを、応答メッセージに加える。
hiscore_records[]
の
i番目の要素の名前をを、応答メッセージに加える。
131: static void print_my_host_port( int portno ) { ... 138: static int insert_score( score_record_t records[], int len, int nelement, 139: int score, char *user ) { ... 138: static int insert_score( score_record_t records[], int len, int nelement, 139: int score, char *user ) { ...
print_my_host_port()
は、自分自身のホスト名と通信ポート番号を表示する。
insert_score()
と find_posision()
は、
集中のプログラム
と同じ。
167: /* Coins System Program */ 170: void tcp_peeraddr_print( int com ) { ... 183: void sockaddr_print( struct sockaddr *addrp, socklen_t addr_len ) { ... 192: int tcp_acc_port( int portno ) { ...
... 13: struct marbuf { 14: uint32_t mb_bytes; 15: char *mb_current; 16: char *mb_buf; 17: size_t mb_buflen; 18: }; 19: typedef struct marbuf marbuf_t; ...
... 15: int marbuf_init( marbuf_t *mb, size_t buflen ) { 16: if( (mb->mb_buf = malloc(buflen)) == NULL ) { 17: return( 0 ); 18: } 19: mb->mb_buflen = buflen; 20: mb->mb_bytes = 0; 21: mb->mb_current = mb->mb_buf; 22: } ... 24: void marbuf_final( marbuf_t *mb ) { ... 32: int marbuf_receive_message( marbuf_t *mb, int socket ) { 33: uint32_t msglen, msglen_net ; ... 52: int marbuf_send_message( marbuf_t *mb, int socket ) { 53: uint32_t msglen, msglen_net ; 54: msglen = mb->mb_bytes; 55: msglen_net = htonl(msglen); 56: if( write(socket,&msglen_net,sizeof(msglen_net)) != sizeof(msglen_net) ) { 57: perror("write"); 58: return( -1 ); 59: } 60: if( write(socket,mb->mb_buf,msglen) != msglen ) { 61: perror("read"); 62: return( -1 ); 63: } 64: mb->mb_bytes = 0; 65: mb->mb_current = mb->mb_buf; 66: return( msglen ); 67: } 68: 69: int marbuf_marshal_int( marbuf_t *mb, int data ) { 70: uint32_t data_net ; 71: if( mb->mb_bytes + sizeof(data_net) > mb->mb_buflen ) 72: return( 0 ); 73: data_net = htonl( data ); 74: memcpy( mb->mb_current, &data_net, sizeof(data_net) ); 75: mb->mb_current += sizeof(data_net); 76: mb->mb_bytes += sizeof(data_net); 77: return( 1 ); 78: } 79: 80: int marbuf_unmarshal_int( marbuf_t *mb, int *datap ) { 81: uint32_t data_net ; 82: if( mb->mb_bytes + sizeof(data_net) > mb->mb_buflen ) 83: return( 0 ); 84: memcpy( &data_net, mb->mb_current, sizeof(data_net) ); 85: *datap = ntohl( data_net ); 86: mb->mb_current += sizeof(data_net); 87: mb->mb_bytes += sizeof(data_net); 88: return( 1 ); 89: } 90: 91: int marbuf_marshal_byte_array( marbuf_t *mb, char data[], int data_len ) { 92: if( mb->mb_bytes + data_len > mb->mb_buflen ) 93: return( 0 ); 94: memcpy( mb->mb_current, data, data_len ); 95: mb->mb_current += data_len; 96: mb->mb_bytes += data_len; 97: return( 1 ); 98: } 99: 100: int marbuf_unmarshal_byte_array( marbuf_t *mb, char data[], int data_len ) { 101: if( mb->mb_bytes + data_len > mb->mb_buflen ) 102: return( 0 ); 103: memcpy( data, mb->mb_current, data_len ); 104: mb->mb_current += data_len; 105: mb->mb_bytes += data_len; 106: return( 1 ); 107: }
[Makefile]