トップページ > 過去ログ > 記事閲覧
通信待ち
名前:ライブラリ使用者 日時: 2007/12/10 00:49

 しばらくぶりです。 ある程度のレベルでアプリは完成したのですが、通信接続エラー(待ち?)が発生する場合があります。 発生の条件としては、多人数接続時です。 あとはPC性能は悪い人ほどでしょうか? 原因特定したいのですが、どうにも解析しようがありません。(私自身の環境では再現しません 下記ソースの一部ですが、TIMEOUTを10000(10秒)にすると、接続人数が30人以上になるとこのループが終わりません。(ほぼ全員で、タイムアウトすらしない そこで、60000(60秒)とすると、この問題は解決しました。(最大60名弱まで同時接続チャットできました。 が、何名かはこのループが終わらない人が出てきてしまいます。 状況としてはこのループがまわっていない感じです。 GetNetWorkDataLength()内でも処理待ちなような事は発生しえるのでしょうか? ※エラーの発生ですが、ある時以降全員がなるのではなく、特定の人がなり続けます。 接続できない人がいても、その後に接続試行して繋がる人もおります。 アプリの概要として、スレッド処理にて通信処理してる部分もありますがCriticalSection()を用い、排他的に処理ができていると思います。 長くなりましたが、対応のご助言頂けないでしょうか //タイマー開始 timer = GetNowCount(); while((GetNowCount() - timer) < TIMEOUT) { if(ProcessMessage() == -1) { //エラー処理抜け return 0; } if(CheckHitKey(KEY_INPUT_ESCAPE) == 1) { break;//ESCキーが押されたらループから抜ける } DataLength = GetNetWorkDataLength(GetNetHandle()); if(DataLength > 0) { //データ取得用バッファ確保 char* buf = new char[DataLength]; //接続キャラデータの取得 NetWorkRecv(GetNetHandle(),buf,DataLength); //このタイミングで来た、キャラデータ以外は無視する int DataPos = 0; do { pmsg = (SendMessageType*)&buf[DataPos]; switch(pmsg->Type) { case SMT_ALLEND: //取得完了 Finish = TRUE; break; default: //チャットデータなどはすべて無視する break; } //次ぎのメッセージまで移動する DataPos += pmsg->PacketSize; } while(DataLength > DataPos); delete [] buf; if(Finish) break; }

Page: 1 | 2 | 3 |

Re: 通信待ち ( No.31 )
名前:ライブラリ使用者 日時:2007/12/28 21:35

//接続者データ(共通管理) struct CharaInfo { char Name[MAXNAME]; //キャラ名 char Host[MAXHOST]; //ホスト名 char Guild[MAXGUILD]; //ギルド名 char version[MAXVERSION]; //バージョン IPDATA ip; //IPアドレス int NetHandle; //ネットハンドル int GrpHandle; //キャラ画像ハンドル int JobType; //職 int SexType; //性別 int Experience; //経験値 int Rebirth ; //転生数 DPOINT RealPos; //現在位置座標 POINT MovePos; //移動先座標 double rateX; //1フレーム当りの移動幅(X) double rateY; //1フレーム当りの移動幅(Y) }; >例外としてNGケースの場合は溜まりきっていない >ここから手繰るしかなさそうですね。。。 もしかしたらですが、受信時になお、未受信バッファに溜まり続けるようなタイミングが怪しいのかなとおもったり。 クライアント側でWaitTimer(3-5秒)とかやればどうかなと今度試すつもり ダンプ処理について 使わせていただきます。
Re: 通信待ち ( No.32 )
名前: 日時:2007/12/29 02:58

もう一点不具合というか、意図してはいないと思われる動作があるので書いておきます。 case SMT_ALLEND: //取得完了 Finish = TRUE; break; 取得完了とありますが、 実際にはこのENDパケットの後にそれ以外の別の パケットが送信されるなどがされた場合フラグ自体 はTRUEになっても、データのサイズを全て処理し 終えるまでは内側のループを抜けません。 (ENDパケットの後に別のパケットが固められて受信された場合) あとは取得中のデータのサイズが大きければ 大きいほど内側のループが回ることになりますが、 その間ProsessMessage関数を呼び出していない為、 Window見えにはストールと判断される可能性が あるようです。 ここでは今は割愛していますが、私が書いたコード では内側のループを以下のように変更しました。 while( DataLength > DataPos );  ↓ while( Finish==FALSE && DataLength > DataPos && !ProcessMessage()); ただし、今回書いた現象で内側のループが無限 ループに陥る事はほぼないと思います。 パケットのサイズに異常がある以外に内側の ループで無限ループになる場合はなさそうなので、 実はProcessMessageの呼び出しがなかったので、 見かけ上、止まっていたということもあるかも しれません。
Re: 通信待ち ( No.33 )
名前:ライブラリ使用者 日時:2007/12/29 13:34

SMT_ALLENDケース時ですが、受信したデータはすべて処理してから、ループを抜けると意図したものです。 チャットですから、ユーザ情報の他にチャットなどのデータも舞い込んできます。 最も現状、それらのデータは切り捨てているのでその場で抜けることに問題はないのですが、今後の拡張性残すためそのような処理にしています。 >あとは取得中のデータのサイズが大きければ 大きいほど内側のループが回ることになりますが、 その間ProsessMessage関数を呼び出していない為、 Window見えにはストールと判断される可能性が あるようです。 その可能性もありますか。。 そこは想定外でした。
受信失敗してる? ( No.34 )
名前:ライブラリ使用者 日時:2007/12/29 21:41

No21でダンプに差異なしと記載しましたが、確認し直した所NG時はデータが壊れている?ようです。 現在テストケースとして、size = sizeof(SendMessageType) + sizeof(CharaInfo); しか送信してないはずなのですが、NG時の時点での受信量はsizeのN倍とはなっておりません。 何回かNG時はループが2回分かれていると書きましたが、順序逆でNGが起きているためにループが一度止まっているのかもしれません。また次ぎのループ時受信で得たデータは壊れてしまっています。  ただ、NetWorkSend、NetWorkRecvはいずれもNGを返していないという状況でした。 1度に受信できる量、もしくはNetWorkSendを溜めれる量に限度があるのかもしれません。 次はこのあたりを確認してみます。。
Re: 通信待ち ( No.35 )
名前: 日時:2008/01/07 02:03

>現在テストケースとして、size = sizeof >(SendMessageType) + sizeof(CharaInfo); >しか送信してないはずなのですが、NG時の時点での >受信量はsizeのN倍とはなっておりません。 ENDパケットはsizeof(CharaInfo)が無いはず なので、必ずしもこのサイズの倍数である保障は ないと思います。 チャットのメッセージなども含めればなおさらです うーん、Dumpの方法をパケットのタイプごとに パケット内のサイズでDumpしてみてはどうでしょう? Dumpの前に任意の文字列とかも出せるように Dump関数を少し改良しました。 追加 #include <stdarg.h> 修正 /* * dump * dump out to file */ int dump( FILE* ofp, void* cdData, unsigned long ulSize, dump_opt type, char* str, ... ) { unsigned long i,j; unsigned long nCurrent,nCnt=0; va_list arg; if( cdData==NULL || ofp==NULL ) return 1; if ( str != NULL ){ va_start( arg, str ); vfprintf( ofp, str, arg ); va_end( arg ); } fprintf( ofp, "\n" ); if ( type == DUMP_ADDRESS ){ fprintf( ofp, "ADDRESS | " ); } else { fprintf( ofp, "OFFSET | " ); } for( j=0; j<MAXBIN_LEN; j++ ) fprintf( ofp, "%02X ", j ); fprintf( ofp, " " ); for( j=0; j<MAXBIN_LEN; j++ ) fprintf( ofp, "%X", j ); fprintf( ofp, "\n" ); for( j=0; j<MAXROW_LEN; j++ ) fprintf( ofp, "-" ); fprintf( ofp, "\n" ); for(i=nCurrent=0; nCurrent<ulSize; i++, nCurrent += MAXBIN_LEN ){ _hex( i, ulSize, nCurrent, cdData, ofp, type ); _ans( i, ulSize, nCurrent, cdData, ofp ); } fprintf( ofp, "\n" ); return 0; } switch文でダンプするデータを分ける #以下は私が書いたテストコードの一部です switch(pTestPacket->Type){ case SMT_END: dump( ofp, (unsigned char*)pTestPacket, pTestPacket->Size, DUMP_OFFSET, "SMT_END:%x Size:%d", pTestPacket->Type, pTestPacket->Size ); Finish = TRUE; break; case SMT_CHAR: dump( ofp, (unsigned char*)pTestPacket, pTestPacket->Size, DUMP_OFFSET, "SMT_CHAR:%x Size:%d", pTestPacket->Type, pTestPacket->Size ); char Draw[256]; sprintf( Draw, "%s: ADDRESS %d.%d.%d.%d", ((CHAR_SUB*)pTestPacket->data)->Name, ((CHAR_SUB*)pTestPacket->data)->ip.d1, ((CHAR_SUB*)pTestPacket->data)->ip.d2, ((CHAR_SUB*)pTestPacket->data)->ip.d3, ((CHAR_SUB*)pTestPacket->data)->ip.d4 ); DrawString( 0 , 16*(dcnt++) , Draw, GetColor( 255 , 255 , 255 )); count++; break; default: dump( ofp, (unsigned char*)pTestPacket, pTestPacket->Size, DUMP_OFFSET, "SMT_?????:%x Size:%d Invalid Packet!!", pTestPacket->Type, pTestPacket->Size ); break; }
Re: 通信待ち ( No.36 )
名前:ライブラリ使用者 日時:2008/01/12 16:05

あけおめ。。 返事が大変に遅れてしまい申し訳ありません。 さらに、ダンプ改良して頂きましたがソースをまともに見る時間もとれていません><  今回は上記エラーが発生するソースを簡単にまとめました。 下記をコンパイルし実行することで、問題発生させることができると思います。 #include "DxLib.h" //名前 #define MAXNAME 17 //ギルド名 #define MAXGUILD 33 //ホスト名 #define MAXHOST 100 //バージョン表記 #define MAXVERSION 20 //送受信データタイプ #define SMT_ADD 1 //接続者データ追加 #define SMT_DELETE 2 //接続者データ削除 #define SMT_CHAT 3 //チャットデータ #define SMT_ALL 4 //接続者全データ #define SMT_ALLEND 5 //接続者全データ(展開終了) #define SMT_DATA 6 //接続者データ(個人) #define SMT_RENEW 7 //接続者データ更新(位置情報) #define SMT_System 8 //管理者特権 //送受信データ型 struct SendMessageType { int Type; //送受信データタイプ int PacketSize; //SendMessageTypeの全サイズ char data[1]; //データ詳細 }; //高精度座標 struct DPOINT { double x; double y; }; //接続者データ(共通管理) struct CharaInfo { char Name[MAXNAME]; //キャラ名 char Host[MAXHOST]; //ホスト名 char Guild[MAXGUILD]; //ギルド名 char version[MAXVERSION]; //バージョン IPDATA ip; //IPアドレス int NetHandle; //ネットハンドル int GrpHandle; //キャラ画像ハンドル int JobType; //職 int SexType; //性別 int Experience; //経験値 int Rebirth ; //転生数 DPOINT RealPos; //現在位置座標 POINT MovePos; //移動先座標 double rateX; //1フレーム当りの移動幅(X) double rateY; //1フレーム当りの移動幅(Y) }; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { int i; int count = 0; int size = 0; int pos; int NetHandle_send; int NetHandle_recv; int DataLength; int flg = 0; char* data; IPDATA ip; //PCに合わせて設定してください ip.d1 = 192; ip.d2 = 168; ip.d3 = 1; ip.d4 = 2; //背景色を設定 SetBackgroundColor(255,255,255); //常に動作させる SetAlwaysRunFlag(TRUE); //ウインドウモードでのプログラム起動 //デフォルトではフルスクリーンモード起動となる ChangeWindowMode(TRUE); // 画面モードの変更 SetGraphMode( 300 , 100 , 16 ); DxLib_Init(); PreparationListenNetWork(); NetHandle_send = ConnectNetWork(ip); WaitTimer(100); NetHandle_recv = GetNewAcceptNetWork(); if((NetHandle_recv == -1) || (NetHandle_send == -1)) { DxLib_End(); return TRUE; } //送信データ作成 CharaInfo test; strcpy(test.Name,"あいうえお"); strcpy(test.Guild,"test-guild"); test.ip.d1=test.ip.d2=test.ip.d3=test.ip.d4=77; strcpy(test.Host,"so-netだよ"); test.NetHandle = -1; test.JobType = 4; test.SexType = 2000; test.RealPos.x = test.MovePos.x = 320; test.RealPos.y = test.MovePos.y = 240; size = sizeof(SendMessageType) + sizeof(CharaInfo); SendMessageType* pmsg = (SendMessageType*)new char [size]; pmsg->Type = SMT_ALL; pmsg->PacketSize = size; ::memcpy(pmsg->data,&test,sizeof(CharaInfo)); while(1) { if( ProcessMessage() == -1 ) { break ; // エラーが起きたらループを抜ける } if(CheckHitKey(KEY_INPUT_ESCAPE ) == 1) { break; } //カウントアップ count += 10; // 画面の初期化 ClearDrawScreen() ; DrawString(10,10,"ESCキーで終了します。",GetColor(0,0,0)); DrawFormatString(10,30,GetColor(0,0,0),"現在%6d回目のループ中です。",count); //裏画面を表示させる ScreenFlip(); //送信(ループ成功する度に送信量を増す) for(i=0; i<count; i++) { //送信データを送信する NetWorkSend( NetHandle_send , pmsg , size ) ; } WaitTimer(100); pos = 0; //受信 DataLength = GetNetWorkDataLength(NetHandle_recv); if(DataLength) { data = new char [DataLength]; NetWorkRecv( NetHandle_recv , data , DataLength ) ; SendMessageType* msg; CharaInfo* info; do { msg = (SendMessageType*)&data[pos]; if(pmsg) { switch(msg->Type) { case SMT_ADD: //この場合も処理いるね。 case SMT_ALL: info = (CharaInfo*)msg->data; if(strcmp(info->Name,test.Name) != 0) { ::MessageBox(NULL,"データエラー。",NULL,MB_OK); } break; case SMT_ALLEND: break; case SMT_DELETE: break; default: break; } //次ぎのメッセージまで移動する if((msg->PacketSize <= 0) || (msg->PacketSize > DataLength)) { ::MessageBox(NULL,"サイズエラー。",NULL,MB_OK); //ループ抜けさせる msg = NULL; flg = 1; break; } else { pos += msg->PacketSize; } } else { //ループ抜けさせる flg = 1; break; } }while(DataLength > pos); delete [] data; if(flg) { break; } } } delete [] pmsg; ::MessageBox(NULL,"OK押下するとプログラムが終了します。","スタブアプリ",MB_OK); CloseNetWork(NetHandle_send); CloseNetWork(NetHandle_recv); DxLib_End(); return TRUE; }
Re: 通信待ち ( No.37 )
名前:ライブラリ使用者 日時:2008/01/12 16:12

上記ソースですが、 SendMessageTypeを10回単位で送信するプログラムです。送信、受信、データ照合を行い問題が無ければ、 +10回を繰り返していきます。 (エラーまたは止めるまでループします) 環境次第でしょうが、私の所では200回前後から発生します。 そいや、環境あげたことなかった気がしますね。。 OS:XP Pro メモリ:2GB グラボ:GeForce8800 ツール:VC6.0+SP4? SP6はもってなかったりする。。 まだどっかに置いてあるのでしょうかね・・・ ※エラー処理など多少甘い部分ありますが、そこはご勘弁ください。
Re: 通信待ち ( No.38 )
名前:Will 日時:2008/01/12 20:09

出先で実行環境が無いので試してはいませんが、ソースを見ての指摘をいくつか。 まずNetWorkSendの戻り値はチェックしたほうが良いのではないですか? 送信時点で失敗した時は受信も正しく動作しない可能性が高いですから、その時の結果は無視するべきだと思います。 DXライブラリの通信方式がどうなっているのか良くわからないですが、NetWorkSendを複数回実行した後にGetNetWorkDataLengthを一度だけ実行していますが、この間に全ての送信データが必ず相手側の受信バッファに格納されることが保障されているのでしょうか?(リファレンス読む限りだとそう読めるけど) 保障されているのであれば、送信したデータサイズの合計とGetNetWorkDataLengthのサイズが一致することをチェックしたほうがいいと思います。 一つのクライアントに対してどれだけの受信バッファをDXライブラリが確保しているのかはわかりませんが、無限ということは無いでしょうから永久に失敗しないことはどんな環境であっても無いような気がします。
Re: 通信待ち ( No.39 )
名前:ライブラリ使用者 日時:2008/01/12 21:25

Willさん 実際のソースでは戻り値チェックしています。 今回はあくまで質問の問題を再現させるサンプルソースとして作成しただけですので、 ※エラー処理など多少甘い部分ありますが、そこはご勘弁ください。 と明記しました。 この間に全ての送信データが必ず相手側の受信バッファに格納されることが保障されているのでしょうか? →この答えはYESでもあるNOでもあります。 NetWorkSendを複数回実行した後に、1度のGetNetWorkDataLengthですべて受信できることは確認済みです。 ただし、ネット環境やタイムラグの都合により全て受信できない場合は当然あると思います。 送信したデータサイズの合計とGetNetWorkDataLengthのサイズが一致することをチェックしたほうがいいと思います。 →今回のサンプルソースであれば、その方法によるチェックでも構わないと思いますが、実際は多クライアントから無差別にデータ送受信が発生します。 また、実際のソースではGetNetWorkDataLengthをメインループ内で呼んでいますので、2番目の質問事項である受信バッファにいくつ入るかは保障されていません。 以上の理由からデータサイズの一致チェックはしていません。 無限ということは無いでしょうから永久に失敗しないことはどんな環境であっても無いような気がします。 →上限があるのであればそれを知りたい訳です。 また、現状では上限には未達(?)でありながら、失敗するケースがありますので、それを追求したいのです。 補足:今回のサンプルで無限ループにした訳は、個人の環境により問題発生するバッファが異なると思われるためです。
Re: 通信待ち ( No.40 )
名前:mas 日時:2008/01/12 21:52

私の環境では600回ほどでエラーになりました。 > data = new char [DataLength]; > NetWorkRecv( NetHandle_recv , data , DataLength ) ; 中略 > }while(DataLength > pos); これでは、中途半端なパケットがあった場合ループを抜けると破棄されますね。 アドホックですが、以下の修正を加えることによって、 2000回を超えてもエラーが発生しませんでした。 NetWorkRecv( NetHandle_recv , data , DataLength/size*size ) ; 中略 }while(DataLength > pos+size);
Re: 通信待ち ( No.41 )
名前:ライブラリ使用者 日時:2008/01/13 02:18

masさん 中途半端なパケットがあった場合ループを抜けると破棄されますね。 →これはエラー時ということでしょうか? 今までの確認の中で、NetWorkRecvで受信できるデータサイズはNetWorkSendで送信したサイズのみで、半端なデータとしては受信しない作りということは分かっています。  ですので、本来中途半端なパケットは存在しないはずなのですが、稀に混ざってしまいます。 (たぶんそれが今回の問題の原因?) それを取り除きたいと思っているのですが、なかなかうまくいかず。 masさんの修正はあとで確認してみますが、 残念ながらというか、実際のソースでは送信データはsize固定ではないので、その方法では解決しませんね。。  やはりNetWorkRecvToPeekで受信データを切り分ける方法がよさげなのかな。。
Re: 通信待ち ( No.42 )
名前:mas 日時:2008/01/13 08:53

> 今までの確認の中で、NetWorkRecv() で受信できるデータサイズは NetWorkSend() で送信したサイズのみで、 > 半端なデータとしては受信しない作りということは分かっています。 リファレンスを見る限りでも、DXライブラリのソースを眺めた限りでも(軽くですが)、 そのような情報が見当たらないのですが、どこかにあるのでしょうか? NetWorkRecv() は 第三引数の Length で指定したデータ量が受信されていたら取得するものだと私は解釈しています。 (通常の recv() では引数で指定したバッファサイズより少ないデータが返されることがあり、  それに対処するためにDXライブラリ側でバッファリングしているのではないかと) > masさんの修正はあとで確認してみますが、 > 残念ながらというか、実際のソースでは送信データはsize固定ではないので、その方法では解決しませんね。。  > やはりNetWorkRecvToPeekで受信データを切り分ける方法がよさげなのかな。。 はい、その通りです。ですからアドホックと書きました。 実際は、もう少し工夫する必要がありますね。
Re: 通信待ち ( No.43 )
名前: 日時:2008/01/13 12:49

>>NetWorkRecv() で受信できるデータサイズは >>NetWorkSend() で送信したサイズのみで、 NetWorkRecvではなく、GetNetWorkDataLengthが 返すサイズの事ですね。 ちなみにNetWorkRecvはリファレンスいは以下の記載 「要求データ量よりも一時記憶バッファに保存され  ている データ量の方が少ない場合はこの関数は  失敗します」 >そのような情報が見当たらないのですが >どこかにあるのでしょうか? このスレッドのNo18あたりで 管理人さんが答えています。 半端なパケットの指摘は結構前にしたのですが、 DXライブラリの作りとして既にそこは吸収されているようです >Length で指定したデータ量が受信されていたら >取得するものだと私は解釈しています。 私もそう認識しています。 上記と先のGetNetWorkDataLengthの仕様を 考えるとライブラリ使用者さんの言うとおり、 「本来中は存在しないはず」なわけです。 私の環境では3330回のところでエラーがでました。 正常に終わった場合のDump 043712D8 | 00 00 00 00 04 00 00 00 FC 00 00 00 82 A0 82 A2 ................ 043712E8 | 82 A4 82 A6 82 A8 00 00 00 00 00 00 00 73 6F 2D .............so- 043712F8 | 6E 65 74 82 BE 82 E6 00 00 00 00 00 00 00 00 00 net............. 04371308 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 04371318 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 04371328 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 04371338 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 04371348 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 04371358 | 00 74 65 73 74 2D 67 75 69 6C 64 00 00 00 00 00 .test-guild..... 04371368 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 04371378 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 04371388 | 00 00 00 00 00 00 00 00 4D 4D 4D 4D FF FF FF FF ........MMMM.... 04371398 | 00 00 00 00 04 00 00 00 D0 07 00 00 00 00 00 00 ................ 043713A8 | 00 00 00 00 00 00 00 00 00 00 74 40 00 00 00 00 ..........t@.... 043713B8 | 00 00 6E 40 40 01 00 00 F0 00 00 00 00 00 00 00 ..n@@........... 043713C8 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ******************************************************************************** サイズエラーの直前Dump 0435CCB8 | 00 00 00 00 00 00 00 00 04 00 00 00 FC 00 00 00 ................ 0435CCC8 | 82 A0 82 A2 82 A4 82 A6 82 A8 00 00 00 00 00 00 ................ 0435CCD8 | 00 73 6F 2D 6E 65 74 82 BE 82 E6 00 00 00 00 00 .so-net......... 0435CCE8 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0435CCF8 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0435CD08 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0435CD18 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0435CD28 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0435CD38 | 00 00 00 00 00 74 65 73 74 2D 67 75 69 6C 64 00 .....test-guild. 0435CD48 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0435CD58 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0435CD68 | 00 00 00 00 00 00 00 00 00 00 00 00 4D 4D 4D 4D ............MMMM 0435CD78 | FF FF FF FF 00 00 00 00 04 00 00 00 D0 07 00 00 ................ 0435CD88 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 74 40 ..............t@ ******************************************************************************** サイズエラーのDump * [NoteMessages:PK TYPE:UNKWON(0) Data Size:0 Dump is Header Only] ADDRESS | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 0123456789ABCDEF ---------------------------------------------------------------------------- 04350048 | 00 00 00 00 00 00 00 00 00 ......... ******************************************************************************** これをみると直前のパケットの最後が微妙に 違っているので、これかもしれませんね。。。
Re: 通信待ち ( No.44 )
名前:mas 日時:2008/01/13 14:22

> このスレッドのNo18あたりで管理人さんが答えています。 情報ありがとうございます。見てきました。 これで仕様なのかバグなのかが少しずつわかってきた気がします。 > 受信データサイズが NetWorkSend で送信された > データサイズ以上になるまで GetNetWorkDataLength 関数の戻り値には > 受信データとして反映されないようになっています。 管理人さんが上記のように説明されてますが、 DxWin.cpp の RecvSocket() を見る限り、そのような動作にはなっておらず、 中途半端に受信した状態が存在しえると思います。 具体的には、9680行目以降のループを break で抜けてしまうことが原因と予想しています。
Re: 通信待ち ( No.45 )
名前: 日時:2008/01/14 07:50

DXライブラリソースコード公開してたんですね。。 気づかなかった。。。 >DxWin.cpp の RecvSocket() を見る限り >9680行目以降のループをbreak で >抜けてしまうことが原因と予想 確かにこのあたりのBreckで抜けると、 関数戻り値が0でチェック側はRet<0になっている っぽいので継続した上に受信処理を行う継起が あるようですね。。。
Re: 通信待ち ( No.46 )
名前:管理人 日時:2008/01/14 13:44

> DxWin.cpp の RecvSocket() を見る限り、そのような動作にはなっておらず、 > 中途半端に受信した状態が存在しえると思います。  今ライブラリのプログラムを見直してみたのですが・・・・ 仰る通りです。NetWorkSend で送信されたデータを受信しきっていなくても GetNetWorkDataLength で取得できるデータ容量は増えてしまっています。orz  受信しきるまでは GetNetWorkDataLength の値は変化しないというのは私の 妄想だったようです。申し訳ありません・・・m(_ _;m  妄想(受信しきるまでは GetNetWorkDataLength の値は上がらない)を具現化した バージョンをアップしましたので、もし宜しければお試しになってみて下さい。  一応、こちらではライブラリ使用者さんが貼って下さったテストプログラムで 何カウントしてもエラーが発生しないことは確認できています。 http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe //VC用 http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe //BCC用 (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』、VCをお使いの場合は『リビルド』をして下さい) なお、VC版は今回のバージョンからプロジェクトで使用するランタイムライブラリを   デバッグビルド時は マルチスレッド デバッグ(/MTd) を   リリースビルド時は マルチスレッド(/MT) を 使用するように設定する必要がありますので、お手数ですがご変更の程お願い致します。
Re: 通信待ち ( No.47 )
名前:ライブラリ使用者 日時:2008/01/14 20:55

皆様、回答有難うございます。 また、管理人様ご対応ありがとうございました。 早速サンプルの方で試した所、1000回ループ複数回実施し問題ありませんでした。 ただ、Debug版ですがマルチスレッド デバッグ(/MTd) を設定しても下記エラー出ています。 (Release版は問題なし) DxLib_d.lib(DxDraw.obj) : error LNK2001: 外部シンボル ""int __cdecl StreamOpen(char const *,int,int)" (?StreamOpen@@YAHPBDHH@Z)" は未解決です Debug/StabClient.exe : fatal error LNK1120: 外部参照 1 が未解決です。 この後、実際のソースでもリビルドして確認してみます。
Re: 通信待ち ( No.48 )
名前:ライブラリ使用者 日時:2008/01/14 22:51

LNK2001ですが、Ver2.24aでリビルドした所問題ありませんでした。 実際のソースで実施した結果ですが、500人(回)で確認しているのですが369人分しかデータ受信していません。ただし、受信は最後までしているようです。 Debug版での動作は未確認ですので、実際にデータがどうなっているかはまでは分かりませんでした。。
Re: 通信待ち ( No.49 )
名前:管理人 日時:2008/01/15 00:40

申し訳ありません、Debug版が正常にビルドされていなかったみたいです。 リビルドしたバージョンをアップしましたので、宜しければもう一度お試しに なってみて下さい。m(_ _;m http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe //VC用 http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe //BCC用
Re: 通信待ち ( No.50 )
名前:ライブラリ使用者 日時:2008/01/15 22:28

デバック版、リリース版ちゃんとビルドできました。 対応ありがとうございます。

Page: 1 | 2 | 3 |