通信プログラムの試作ーーー UDP を用いたじゃんけんゲームシステム ーーーー裘彬濱 南山大学情報理工学部 ソフトウェア工学科青山研究室

Similar documents
目次 1. DB 更新情報受信 SW 仕様書 構成および機能 全体の構成 DB 更新情報受信 SW の機能 ソフトウェアの設計仕様 DB 更新情報受信 SW の仕様 資料編... 5

演算増幅器

実験 6 通信基礎実験 1 目的 ネットワークを通じてデータ転送を行うことを体験的に学ぶために 本実験ではT CP/IPプロトコルを使い ワークステーション間で通信を行うクライアントサーバモデルのプログラムを作成する 2 解説 1 ネットワークとプロトコルネットワーク ( コンピュータネットワーク

BSDソケットによるIPv6プログラミングを紐解く

TCP UDP TCP UDP send()sendto()sendmsg() recv()recvfrom()recvmsg() OS Passive Active TCP UDP IP TCP UDP MTAMail Transf

4 実験結果 // 用意されたヘッダファイル #include < stdio.h> #include < fcntl.h> #include < netdb.h> #include < sys/types.h> #include < sys/socket.h> #include < sys/sta

slide5.pptx

3 3.1 LAN ISDN (IP) 2 TCP/UDP IP IP IP IP (Ethernet) Ethernet LAN TCP/UDP LAN Ethernet LAN 2: Ethernet ATM, FDDI, LAN IP IP IP 3 IP 2 IP IP IP IP IP 3

Taro-リストⅢ(公開版).jtd

main main Makefile Makefile C.5 Makefile Makefile Makefile A Mech (TA ) 1. Web ( iku

Si 知識情報処理

Taro-リストⅠ(公開版).jtd

TFTP serverの実装

Microsoft Word - EGX100によるH663通信手引

演算増幅器

文字数は1~6なので 同じ本数の枝を持つパスで生成される呪文の長さは最大で6 倍の差がある 例えば 上図のようなケースを考える 1サイクル終了した時点では スター節点のところに最強呪文として aaaaaac が求まる しかしながら サイクルを繰り返していくと やがてスター節点のところに aaaaaa

Prog1_10th

Prog1_15th

ohp03.dvi

ネーミング(1)

/*

PowerPoint プレゼンテーション

1 telnet WWW 1.1 telnet WWW URL html 1.2 URL 1 % telnet 80 Trying 2001:2f8:1c:d048::850d: telnet: c

I. Backus-Naur BNF : N N 0 N N N N N N 0, 1 BNF N N 0 11 (parse tree) 11 (1) (2) (3) (4) II. 0(0 101)* (

エラー処理・分割コンパイル・コマンドライン引数

画像ファイルを扱う これまでに学んだ条件分岐, 繰り返し, 配列, ファイル入出力を使って, 画像を扱うプログラムにチャレンジしてみよう

<4D F736F F D20438CBE8CEA8D758DC F0939A82C282AB2E646F63>

untitled

r03.dvi

// このクラスの有効期間中の各呼び出しに使用される キャッシュされた Socket オブジェクト Socket socket = null; // 非同期処理が完了したことを通知するために信号を送るオブジェクト static ManualResetEvent clientdone = new Ma

プログラミング基礎

PowerPoint プレゼンテーション

II ( ) prog8-1.c s1542h017%./prog8-1 1 => 35 Hiroshi 2 => 23 Koji 3 => 67 Satoshi 4 => 87 Junko 5 => 64 Ichiro 6 => 89 Mari 7 => 73 D

【注意事項】RXファミリ 組み込み用TCP/IP M3S-T4-Tiny

I. Backus-Naur BNF S + S S * S S x S +, *, x BNF S (parse tree) : * x + x x S * S x + S S S x x (1) * x x * x (2) * + x x x (3) + x * x + x x (4) * *

‚æ4›ñ

DA100データアクイジションユニット通信インタフェースユーザーズマニュアル

char int float double の変数型はそれぞれ 文字あるいは小さな整数 整数 実数 より精度の高い ( 数値のより大きい より小さい ) 実数 を扱う時に用いる 備考 : 基本型の説明に示した 浮動小数点 とは数値を指数表現で表す方法である 例えば は指数表現で 3 書く

Microsoft PowerPoint - lec10.ppt

ソフトウェア開発実践セミナー ネットワークの基礎と UNIX ネットワークプログラミング 金子勇 土村展之 情報理工学系研究科数理情報学専攻 2002 年 11 月 6 日 ( 第 4

PowerPoint プレゼンテーション

Taro-2分探索木Ⅱ(公開版).jtd

Cプログラミング - 第8回 構造体と再帰

Microsoft Word - no15.docx

コマンドラインから受け取った文字列の大文字と小文字を変換するプログラムを作成せよ 入力は 1 バイトの表示文字とし アルファベット文字以外は変換しない 1. #include <stdio.h> 2. #include <ctype.h> /*troupper,islower,isupper,tol

r08.dvi

PowerPoint プレゼンテーション

Microsoft PowerPoint - 第3回目.ppt [互換モード]

ohp08.dvi

Taro-ファイル処理(公開版).jtd

r07.dvi

演算増幅器


ohp07.dvi

IP L09( Tue) : Time-stamp: Tue 14:52 JST hig TCP/IP. IP,,,. ( ) L09 IP (2017) 1 / 28

C 言語講座 Vol 年 5 月 29 日 CISC

: CR (0x0d) LF (0x0a) line separator CR Mac LF UNIX CR+LF MS-DOS WINDOWS Japan Advanced Institute of Science and Technology

C による数値計算法入門 ( 第 2 版 ) 新装版 サンプルページ この本の定価 判型などは, 以下の URL からご覧いただけます. このサンプルページの内容は, 新装版 1 刷発行時のものです.

超初心者用

Microsoft PowerPoint - prog03.ppt

Taro-スタック(公開版).jtd

Cプログラミング1(再) 第2回

プログラミングA

Microsoft Word - report#8.docx

memo

cp-7. 配列

:30 12:00 I. I VI II. III. IV. a d V. VI

memo

橡Pro PDF

プログラミングA

Taro-2分探索木Ⅰ(公開版).jtd

(Microsoft Word - BBT\216\346\220\340SiTCP-VME-Master_Rev11_.doc)

:30 12:00 I. I VI II. III. IV. a d V. VI

kiso2-09.key

ポインタ変数

PowerPoint プレゼンテーション

Prog1_6th

プログラミングA

Taro-再帰関数Ⅱ(公開版).jtd

本研修について mruby 概要 mruby IoT フレームワーク Plato mruby ポーティング mruby ポーティング環境への Plato の適用 2

PowerPoint プレゼンテーション

void hash1_init(int *array) int i; for (i = 0; i < HASHSIZE; i++) array[i] = EMPTY; /* i EMPTY */ void hash1_insert(int *array, int n) if (n < 0 n >=

* ライブラリ関数 islower(),toupper() を使ったプログラム 1 /* 2 Program : trupper.c 3 Student-ID : K 4 Author : TOUME, Kouta 5 Comments : Used Library function i

研究室LANの設定方法

1) // 2) I/O 3) Japan Advanced Institute of Science and Technology 2013/07/26 1

第2回

PowerPoint プレゼンテーション

SoC Linux 道場 【其ノ八】 ネットワーク・アプリでの遠隔 PWM 制御、モーター制御、起動スクリプトの作成方法

プログラミング方法論 II 第 14,15 回 ( 担当 : 鈴木伸夫 ) 問題 17. x 座標と y 座標をメンバに持つ構造体 Point を作成せよ 但し座標 は double 型とする typedef struct{ (a) x; (b) y; } Point; 問題 18. 問題 17 の

1 1.1 C 2 1 double a[ ][ ]; 1 3x x3 ( ) malloc() 2 double *a[ ]; double 1 malloc() dou

1 1.1 C 2 1 double a[ ][ ]; 1 3x x3 ( ) malloc() malloc 2 #include <stdio.h> #include

C¥×¥í¥°¥é¥ß¥ó¥° ÆþÌç

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

double 2 std::cin, std::cout 1.2 C fopen() fclose() C++ std::fstream 1-3 #include <fstream> std::fstream fout; int a = 123; fout.open( "data.t

情報工学実験 C コンパイラ第 2 回説明資料 (2017 年度 ) 担当 : 笹倉 佐藤

RX ファミリ用 C/C++ コンパイラ V.1.00 Release 02 ご使用上のお願い RX ファミリ用 C/C++ コンパイラの使用上の注意事項 4 件を連絡します #pragma option 使用時の 1 または 2 バイトの整数型の関数戻り値に関する注意事項 (RXC#012) 共用

£Ã¥×¥í¥°¥é¥ß¥ó¥°ÆþÌç (2018) - Â裵²ó ¨¡ À©¸æ¹½Â¤¡§¾ò·ïʬ´ô ¨¡

問 2 ( 型変換 ) 次のプログラムを実行しても正しい結果が得られない 何が間違いかを指摘し 正しく修正せよ ただし int サイズが 2 バイト long サイズが 4 バイトの処理系での演算を仮定する #include <stdio.h> int main( void ) { int a =

1.ppt

fp.gby

Transcription:

通信プログラムの試作ーーー UDP を用いたじゃんけんゲームシステム ーーーー裘彬濱 南山大学情報理工学部 ソフトウェア工学科青山研究室

1:UDP を用いたじゃんけんゲームシステムの概要 本システムは通信プロトコル UDP を用いた簡単なじゃんけんゲームシステムであり 単一のユーザ ( クライアント ) が参加し パソコン ( サーバ ) とじゃんけんゲームするシステムである 本システムはユーザがゲームに参加できる時間を制限しており 制限時間にオーバーすると サーバが止まるようになっている 本システムは優勝条件を定めており 優勝条件を満たした側に優勝者になり ゲームを終了させる 2: 応用プロトコルの説明 ( 通信順 ) C S ----- 開始 ------> (UDP の開始メッセージ ) <-ゲーム参加要請 -- --- 参加 / 不参加 --> ( じゃんけんの手 推定した数字 ) <---- 応答 ----- ( 結果 ) ( 以後くりかえし ) <---- 終了 ----- ( 優勝 / 制限時間オーバーしたら UDP の終了メッセージ ) time V V 応用プロトコルの説明 ( メッセージ形式 ) メッセージは簡単な文字列とする 区切りに CRLF を使い この単位で送受信する <1> クライアントからサーバ ( コマンド / 要求 ) 開始メッセージ CRLF ー 最初にクライアントからの開始メッセージが1 文字でなくてもいいが メッセージの内容が重要ではないので 1 文字でデータにした 参加 / 不参加 CRLF ー 参加は y 不参加は n

手 / 終了命令 CRLF ー 手はグー (r) チョキ (s) パー (p) で ゲーム終了は q で 処理が簡単になる <2> サーバからクライアント ( 応答 ) OK SP 説明文字列 CRLF NG SP 説明文字列 CRLF 説明文字列は簡潔なものにする 3: プログラム処理の流れの説明クライアントサーバ ---------------------------------------------------------------- sock = socket() ssock= socket() bind(ssock,,) -- 受付ポート設定ループ始め一回目 send(sock) -------------------> recv(sock,,) recv(sock) <------------------ send(sock,,) 二回目以降 ループ始め send(sock) -------------------> recv(sock,,) recv(sock) <------------------ send(sock,,) -------------------> --- ( 制限時間 <------------------ ( 制限時間オーバー )------- オーバー通知 ) ::: -------------------> 結果通知 <------------------ send(sock,,)( 優勝 ) ループ終わり ループ終わり 終了 終了 4: プログラムの実現 <1> 優勝の判断 サーバ側 int champion=3; ::: wins++; if(wins==champion){ sendto(sock,"-you lost!game over",20, 0,(const struct sockaddr *) &remote,

remotelen);return 0; else if ((handc==0 &&hands==2) (handc==1 &&hands==0) (handc==2 &&hands==1)){ winc++; if(winc==champion){ sendto(sock,"+you're the CHAMPION",20, 0,(const struct sockaddr *) &remote, remotelen);return 0; クライアント側 if(recvbuf[0]=='+' recvbuf[0]=='-')return 0; /******************************************************************* もしサーバが優勝したら クライアントに -You lost!game over というメッ セージを送る メッセージの頭文字 ー と + はクライアント側にゲーム結 果の符号である *******************************************************************/ <2> 制限時間をオーバーした場合の処理 struct fd_set fds,readfds; int n; struct timeval tv; ::: while(1){ ::: FD_ZERO(&readfds); FD_SET(sock,&readfds); tv.tv_sec=10; tv.tv_usec=0; memcpy(&fds,&readfds,sizeof(fd_set)); n=select(sock+1,&fds,null,null,&tv); if(n==0){ sendto(sock,"-time over!!",20, 0,(const struct sockaddr *) &remote, remotelen); printf("time over\n"); return 0; :::

5: テスト <1> テスト項目 ---1: ゲームに参加 / 不参加の返事に対するサーバ側の処理ー y/n を入力された場合と他のアルファベットを入力された場合に対するサーバ側の処理を確認する ---2: 制限時間をオーバーした場合に対するサーバ側の処理ー クライアントは制限時間内に返事しない時に サーバが正しく止まるかを確認する ---3: 制限時間オーバーによりサーバが止まった後 クライアントは送信した場合に対するクライアント側の処理ー サーバからの終了メッセージを正しく受信したか クライアントが正しく処理したかを確認する ---4: 優勝に対する処理ー 優勝の条件を満たした場合に対する処理を確認する ---5: クライアントからの手に対する処理ー クライアントから r/p/s または q を受けた場合とそれら以外の場合の処理 テスト結果 ---1: ゲームに参加 / 不参加の返事に対するサーバ側の処理結果 クライアントの入力サーバの応答テスト結果 y/n Input r/p/s or q. w Erro,input y / n! ---2: 制限時間をオーバーした場合に対するサーバ側の処理制限時間を過ぎると サーバが time over を出力し 止まった しかし この時点で クライアントに終了メッセージを正しく送ったかは確認できない 3 確認結果に移る ---3: 制限時間オーバーによりサーバが止まった後 クライアントは送信した場合に対するクライアント側の処理サーバが止まった後 クライアントは送信し 送信前に受け取ったサーバの終了メッセージ -Time over!! を表示し クライアントプログラムが終了したことを確認した

---4: 優勝に対する処理 サーバクライアントテスト結果 サーバが優勝した 止まった サーバから受信 -You lost!game over クライアントが優勝 した 止まった サーバから受信 +You're the CHAMPION ---5: クライアントからの手に対する処理 クライアントの手サーバの応答テスト結果 r/p/s 正しく判断 q -Game over を送信した後 止まった w Erro,input again! 6: 考察と感想サーバとクライアントとのデータの送受信については どうも二回連続送受信ができない ( と思っている ) 送信した後は受信を待ちである また 送信するデータの長さが長くなると 一部しか送信 ( 受信 ) できない この点については 自分が間違っていると思っているが サーバからの sock にデータの長さを書いても クライアント側が一部しか表示できなかった どこが門題になるのがどうしても見つからず 結局やり方を変えて 簡潔なメッセージを送受信することにした 7: 参考文献 UDP を聞ってみよう (2) URL ーー http://x68000.q-e-d.net/~68user/net/udp-2.html select を聞う ( タイムアウト付き ) URL ーー http://www.geekpage.jp/programming/winsock/select-with-timeout.php

クライアントプログラム #include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <sys/socket.h> // inet_addr #include <netinet/in.h> // inet_addr #include <arpa/inet.h> // inet_addr #include <string.h> // strncpy int main(){ struct sockaddr_in remote; char sendbuf[10], recvbuf[20]; int sock, ret; sock = socket(pf_inet,sock_dgram,0); remote.sin_family = AF_INET; remote.sin_port = htons(60000); remote.sin_addr.s_addr = inet_addr("127.0.0.1"); strncpy(sendbuf,"1",1); while(1){ ret = sendto(sock, sendbuf,6, 0, (const struct sockaddr *) &remote, sizeof(remote)); ret = recvfrom(sock, recvbuf, sizeof(recvbuf)+20, 0, NULL, NULL); if (ret < 0) return -1; recvbuf[ret] = '\0'; printf("%s\n", recvbuf); if(recvbuf[0]=='+' recvbuf[0]=='-')return 0; fgets(sendbuf,sizeof(sendbuf),stdin); return 0;

サーバプログラム #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <stdlib.h> #include <string.h> int main(){ struct sockaddr_in local, remote; char recvbuf[1500],join[1024]="join the game?(y/n)"; int sock,champion=3,winc=0,wins=0; socklen_t remotelen = sizeof(remote); sock = socket(pf_inet,sock_dgram,0); local.sin_family = AF_INET; local.sin_port = htons(60000); local.sin_addr.s_addr = htonl(inaddr_any); if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0) {printf("error\n"); return -1; recvfrom(sock, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *) &remote, &remotelen); // remotelen sendto(sock,join,strlen(join)+1, 0, (const struct sockaddr *) &remote, remotelen); while(1){ // 返事待ち recvfrom(sock, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *) &remote, &remotelen); // remotelen if(recvbuf[0]=='n')break; else if(recvbuf[0]=='y'){ sendto(sock,"input r/p/s or q.",20, 0,(const struct sockaddr *) &remote, remotelen); while(1){ int handc,hands=(int) (3.0*random()/(RAND_MAX+1.0));// サーバの手 recvfrom(sock, recvbuf, sizeof(recvbuf), 0,

(struct sockaddr *) &remote, &remotelen); // remotelen // クライアントの手の決定 if (recvbuf[0] == 'q') break; else if (recvbuf[0] == 'r') handc = 0; else if (recvbuf[0] == 'p') handc = 1; else if (recvbuf[0] == 's') handc = 2; else { sendto(sock,"erro,input again!",20,0, (const struct sockaddr *) &remote, remotelen); continue; if((handc==0 &&hands==1) (handc==1 &&hands==2) (handc==2 &&hands==0)){ wins++; if(wins==champion){ sendto(sock,"-you lost!game over",20, 0,(const struct sockaddr *) &remote, remotelen);return 0; sendto(sock,"you lost!try again",20, 0,(const struct sockaddr *) &remote, remotelen); else if ((handc==0 &&hands==2) (handc==1 &&hands==0) (handc==2 &&hands==1)){ winc++; if(winc==champion){ sendto(sock,"+you're the CHAMPION",20, 0,(const struct sockaddr *) &remote, remotelen);return 0; sendto(sock,"you won!next game",20, 0,(const struct sockaddr *) &remote, remotelen); else if((handc==1&&hands==1) (handc==2&&hands==2) (handc==0&&hands==0)){ sendto(sock,"same,input again",20, 0,(const struct sockaddr *) &remote, remotelen); // y/n 以外の文字を入力された場合 else sendto(sock,"erro,input y / n!",20,0, (const struct sockaddr *) &remote, remotelen); return 0;