4

チャンクタイプのHTTP転送を解析する必要があるクライアントを開発しています。私は次のようにエラーを理解しようとして壁に頭をぶつけました。誰かが私のエラーをもう少し早くキャッ​​チできるかもしれないなら、それをいただければ幸いです。問題を要約すると、クライアントがすべてのチャンクを受信して​​いないように見えるため、残りのプロセスが台無しになります。前もって感謝します!

 while(cflag){
    pfile_chunk = malloc(CHUNK_SIZE+1);
    memset(pfile_chunk, 0, CHUNK_SIZE);
    cPtr = pfile_chunk;
    cPtr2 = NULL;
    k=0;
    while(*(cPtr-1) != '\n'){
        k++;
        recv(sock, cPtr, 1, 0);
        cPtr = pfile_chunk+k;
    }
    cPtr2 = strchr(pfile_chunk, '\r');
    *cPtr2 = '\0';
    sscanf(pfile_chunk, "%x", &l);
    if(l == 0)
        break;
    printf("\nServer wants to deliver %ld bytes.\n", l);
    pfile_chunk = realloc(pfile_chunk, l+1);
    memset(pfile_chunk, 0, l);
    recv(sock, pfile_chunk, l, 0);
    fputs(pfile_chunk, f);
    printf("GOT THIS, SIZE %ld:\n%s\n", strlen(pfile_chunk), pfile_chunk);
    //get next \r\n bytes.
    recv(sock, NULL, 2, 0);
}
4

2 に答える 2

5

少なくとも、の戻り値をチェックして、recv期待するバイト数を取得しているかどうかを確認する必要があります。

システムコールは、呼び出し時にソケット受信バッファで使用可能なものをすべて返すため、ネットワーク上でショートリードが確実に可能です。

チャンク全体を読み込むまでループを実装するか、最後のパラメーターでMSG_WAITALLフラグを渡します。recvただし、からのエラーをチェックする必要がありますrecv

ssize_t r = recv(sock, pfile_chunk, l, MSG_WAITALL);
if (r < l) {
    /* check for errors ... */
} else {
    /* got the data */
}
于 2012-07-23T22:27:09.077 に答える
2

ループ内のチェックの最初の逆参照が配列の開始前にアクセスするように見えますwhileが、これは望ましくない動作である可能性があります。うまくいけば、そのメモリ位置には通常は含まれません\n。それはあなたを台無しにする可能性がありますread。おそらく、あなたに関係する情報が含まれていると思いますが、そうmallocなる可能性は低いので\n、そこから問題が発生することはないかもしれません。

CHUNK_SIZE+1また、うまくいけば、ソケットのもう一方の端が、を与える前よりも多く送信しないことを信頼できます\n。そうしないと、セグメンテーション違反が発生する可能性があります。通常、送信者は10個以下のASCII数字とチャンクヘッダーのCRLFを送信することを期待しますが、理論的には、長いチャンク拡張ヘッダーフィールドの束を一緒に送信できます。

それとは別に、user315052によってすでに見つかったより重要な問題があります。それは、recvメソッドに、要求したすべてのデータを待機するように指示するか、実際に読み取ったデータの量を確認する必要があるということです。

于 2012-10-11T18:46:50.580 に答える