0

TCP ソケット経由で接続されたテスト機器から 6kB のデータをダウンロードしています。私はSOCK_STREAMを使用しています:

if((MySocket=socket(PF_INET,SOCK_STREAM,0))==-1) exit(1);

バッファ サイズを設定していないので、デフォルトを使用していると仮定します。データの受信に問題があります。声明は次のとおりです。

  if((recv(MySocket, &YRaw[indx], sizeChunk*2, 0))==-1)
     {perror("recv()"); exit(9); }  // where sizeChunk=3000; sizeof(YRaw[0])=2

ここで、YRaw は 3000 オブジェクト配列で、各オブジェクトは 2 バイトです。

コードを実行した後に観察した問題は、YRaw 配列の約 3/4 に、配列を初期化したゼロの文字列があることです。受信関数は、配列の 3/4 まで正常に動作し、YRaw 配列のチャンクをスキップして (初期化された値を残して)、再びピックアップし、YRaw 配列がいっぱいになるようです。YRaw 配列でスキップされた値の数に等しい、読み取るバッファーに残っているデータがあります。

これは、システム内のバッファに関連していると思われます。これを修正する方法について誰かが光を当てることができますか?

関連しているかどうかはわかりませんが、次のように TCP_NODELAY も設定しています。

// TCP_NODELAY option minimizes latency by instructing system to send small msgs immediately
// Insert setsockopt() before connect() occurs
int StateNODELAY = 1; // turn NODELAY on
if(setsockopt(MySocket, IPPROTO_TCP,TCP_NODELAY,
   (void *) &StateNODELAY, sizeof StateNODELAY)==-1) {perror("setsockopt()"); exit(2); };

よろしく、gkk

4

2 に答える 2

3

recv()必ずしもバッファ全体を埋めるわけではありません。利用可能なものは何でも読み取り、読み取ったバイト数を返します。

そのため、戻り値を調べて利用可能なデータの量を確認し、そのデータを処理して、recv()期待するすべてのデータを受け取るまで再度呼び出します。

于 2010-08-28T17:27:40.827 に答える
0

の結果を明確に保存する必要がありますrecv(つまり、-1 かどうかをチェックするだけではありません)。これは実際に読み取られたバイトのサイズであり、バッファ内で有効なバイト数を知るために必要です。

それとは別に、ブロックせずにさらにバイトを読み取ることができるかどうかを確認し、ブロックされるまでさらに読み取る必要があります。

バッファ サイズの制限は、イーサネット MTU や送信デバイスなど、システムのどこにでもあります。

于 2010-08-28T17:29:23.787 に答える