トップページ > 過去ログ > 記事閲覧
NetWorkRecv()について
名前:ヨウ 日時: 2013/01/05 21:53

質問させていただきます。 連続してデータを受信する際、 NetWorkRecv()で指定する格納先をmalloc()で確保したアドレスにすると、 それ以降のGetNetWorkDataLength()で正しく値を取得できず、続くデータを受信できません。 // 送信側 =================================================== int sendData[3] = { 0, 1, 2 }; // 通信を確立 IPDATA ip; int port; int netHandle; ip.dall = *; port = *; netHandle = ConnectNetWork( ip, port ); // 確立が成功した場合のみ中の処理をする if( netHandle != -1 ) { // データ送信 for( int i=0; i<3; i++ ) NetWorkSend( netHandle, &sendData[i], sizeof(sendData[i]) ); // キー入力待ち WaitKey(); // 接続を断つ CloseNetWork( netHandle ); } // 受信側 =================================================== int recvData[3]; int port; int netHandle; port = *; // 接続待ち PreparationListenNetWork( port ) ; while( !ProcessMessage() ) { // 新しい接続があったらそのネットワークハンドルを得る netHandle = GetNewAcceptNetWork(); if( netHandle != -1 ){ // 接続の受付を終了する StopListenNetWork(); break; } } // 受信 for( int i=0; i<3; i++ ){ // 取得していない受信データ量を得る int dataLength = GetNetWorkDataLength( netHandle ) ; // 受信完了 if( dataLength != 0 ){ int* temp = (int*)malloc(dataLength); NetWorkRecv( netHandle, temp, dataLength ); recvData[i] = *(int*)temp; } // 受信中 else{ i--; continue; } } // キー入力待ち WaitKey() ; // 接続を断つ CloseNetWork( netHandle ) ; // 以上 ==================================================== // 受信完了 if( dataLength != 0 ){ int* temp = (int*)malloc(dataLength); NetWorkRecv( netHandle, temp, dataLength ); recvData[i] = *(int*)temp; } 上記部分を // 受信完了 if( dataLength != 0 ){ NetWorkRecv( netHandle, &recvData[i], dataLength ); } このようにすると正常に動作します。 関数を間違って使用していたら指摘をおねがいします。

Page: 1 |

Re: NetWorkRecv()について ( No.1 )
名前:Will 日時:2013/01/07 16:46

ざっと見た感じ気になるのはforの中でProcessMessage()を実行していないことぐらいでしょうか。 > それ以降のGetNetWorkDataLength()で正しく値を取得できず、続くデータを受信できません。 を、もう少し具体的に説明してもらえますか。(正しくない値とか、受信できなくでどうなるか等)
Re: NetWorkRecv()について ( No.2 )
名前:ヨウ 日時:2013/01/07 19:45

返答ありがとうございます。 forの中、GetNetWorkDataLengthの前にProcessMessageを実行しましたが、結果は変わりませんでした。 GetNetWorkDataLengthの戻り値が、一度目は12, 二度目以降が毎回0です。 毎回0なのでelseの処理となり、無限ループとなっています。
Re: NetWorkRecv()について ( No.3 )
名前:Will 日時:2013/01/08 11:33

TCPの性質上、4バイト×3を送信したからといって、受信も4バイト×3になるとは限りません。 8、4となることもあれば、今回のように12バイト一回となることもあります。 というか、TCPは送受信の手続きが煩雑なのである程度送信データが溜まってから送信されるので数バイトのデータを連続して送信すると大概そうなります。 下がうまく動くのは単に運がいいだけですね。 送受信するデータが固定長ならその長さで刈り取ればいいですし、 可変長の場合は、パケットの先頭にデータ長を付加して、そのデータ長分受信するのが一般的ですね。 全て刈り取ってから、解析してもいいですけど。(その場合、電文内にセパレータが必要ですが) 今回の場合だとdataLengthが4バイト以上の場合に4バイトずつNetWorkRecv するのが正しいと思います。 # 本当のTCPでは受信データ長が1バイトや2バイトになることもありますが、 そこはDXライブラリがフォローしてます。
Re: NetWorkRecv()について ( No.4 )
名前:ヨウ(解決) 日時:2013/01/14 12:14

なるほど、NetWorkRecvが自動的にデータサイズを分割して受信するのだと勘違いしていました。 パケットの先頭にデータ長を付加する方式を取らせて頂きます。 Willさん、ご指摘ありがとうございました。

Page: 1 |