- - PR -
抜け落ちた番号を再送する方法について(Winsock)
1
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2006-11-22 22:08
こんばんわ。
送信側から各パケットに通番を付加し送信。 受信側で取得できなかった通番を割り出し、送信側へ送信。 というプログラムを構築しています。 受信側を以下に示します。 int rbuf[3000]; //global char recv_Buf[1500]; //local /*パケット受信するために無限ループ*/ while(1){ recvfrom(s,recv_Buf,[省略]); //recvfrom関数にて送信側からのパケットを受信 Seq(recv_Buf); } /*未取得シーケンス番号の割り出し*/ Seq(char *recv_Buf){ int r,x,unseq; int m = 0; static int c = 0; char unseqbuf[30]; memset(unseqbuf,'\0',sizeof(unseqbuf)); sscanf(rbuf,"%d",&r); //通番を整数型で取り出し整数型のrbufへ格納 rbuf[c] = r /*未取得通番の操作*/ if((rbuf[c]-rbuf[c-1])>=2){ m=rbuf[c]-rbuf[c-1]; for(x=1;x<m;x++){ unseq = rbuf[c-1]; unseq += x; sprintf(unseqbuf,"%d",unseq); sendfunc(unseqbuf); } } c++ } sendfunc(char *unseqbuf){ sendto //送信側へ送信 } 上記プログラムのように、無限ループによってパケットを受信し、Seq関数内で取得および未取得通番を割り出し、sendfunc内のsendto関数にて未取得パケットを送信しています。 想定しているパケット数は1000個で、送信側から1000パケット送信。 受信側で未取得通番があれば逐次送信側へ送信しています。 [質問事項] 1.未取得シーケンス番号を割り出して、一度配列に格納し、1回の送信(1パケット)で未取得通番を送信するようにしたいのですが、なにか方法はありますでしょうか? [ メッセージ編集済み 編集者: freebird 編集日時 2006-11-22 22:09 ] [ メッセージ編集済み 編集者: freebird 編集日時 2006-11-22 22:12 ] [ メッセージ編集済み 編集者: freebird 編集日時 2006-11-22 22:46 ] | ||||
|
投稿日時: 2006-11-22 22:40
すばらしい、画期的な方法はありません。単純に受信できたシーケンス番号のリストから、受信できなかったシーケンス番号を割り出すだけです。より高速で、効率の良い方法を知りたいなら、TCPの実装を参考にするのが良いでしょう。 | ||||
|
投稿日時: 2006-11-23 12:36
分かりました。書き込みありがとうございます。 ひとつプログラムを見ていただけないでしょうか。 [質問箇所] int ibuf[3100]; //global /*取得通番の割り出し*/ int Bfunc(char *rbuf){ int num; sscanf(rbuf,"%d",&num); return num; } /*未取得番号の割り出し*/ int Afunc(char *rbuf){ int no,x; int m=0; static int c=0; sscanf(rbuf,"%d",&r); //通番を整数型で取り出し整数型のrbufへ格納 ibuf[c] = r /*未取得通番の操作*/ if((ibuf[c]-ibuf[c-1])>=2){ m=ibuf[c]-ibuf[c-1]; for(x=1;x<m;x++){ no = ibuf[c-1]; return no; no += x; } } c++ } /*whileの無限ループでパケット受信*/ while(1){ int a = 0; int b = 0; char rbuf[1500]; //recvfrom(s,rbuf・・・)関数で受信 a=Afunc(rbuf); b=ABfunc(rbuf); fprintf(fp,"%d\\n",a) //未取得通番をファイルへ書き込み fprintf(fp2,"%d\\n",b) //取得通番をファイルへ書き込み } イメージでは、fpに未取得通番が書き込みされ、fp2に取得通番が書き込みされるのですが・・・同じ通番が書き込みされてしまうという現象が生じます。 どこかおかしいのでしょうか? よろしくお願いします。 | ||||
|
投稿日時: 2006-11-23 17:40
ソースはさらっと眺めただけですが、なぜUDPなのでしょう? 再送を考慮するような場合でUDPを使う必要はないのでは? ユニキャスト以外の通信が必要なのですか? UDPではパケットの重複も欠落も普通にありえますよ。 重複の原因がネットワークかプログラムかの切り分けは出来ていますか? その程度も出来ないようでしたら、UDPでの信頼性の高い通信は無理でしょう。 Programming UNIX Socket FAQをしっかり読んで理解した上で 素直にTCPを使いましょう。TCPでもはまりどころはありますが、 UDPで再送まで含めた実装をするよりは遙かに容易なはずです。 | ||||
|
投稿日時: 2006-11-23 20:37
なんか、「UNIX じゃない、Windows です」なんて返答がある前に、補足。 TCP は、OS に依存しませんから。 あしゅさんが問題にされているのは、プログラムの組み方とか効率的なアルゴリズムとかではなく、もっと下の方、もっと大事な、使用する技術を選ぶための知識です。 freebirdさんが問題とされているところとは違いますが、読んでおいて損はありません。 _________________ | ||||
|
投稿日時: 2006-11-23 23:52
ついでにWinsock Programmer's FAQも読んでおくと良い。http://www.kt.rim.or.jp/~ksk/wskfaq-ja/
| ||||
|
投稿日時: 2006-11-24 15:28
あしゅさん、jittaさん、甕星さん
返答ありがとうございます。
たしかにUNIXではなくWindowsを使用しています。ネットワークプログラミングについて書籍を探しているとUNIXやFreeBSDに実装させて紹介している本(8000円程度の本)を見かけます。とてもハードルが高いと実感しています・・・ 下位層でプログラミングを行うとなれば、WindowsではなくUNIXを利用しなければならないのでしょうか? ソケット関数の表記自体異なるようですし・・・ |
1