6

CIではコードが機能していましたが、なぜ機能するのかわからなかったので、実際に何が起こっているのかを理解できるように書き直しました。

ここまでは順調ですね!私は書き直し、現在起こっていることすべてを理解していると90%確信しています。ただし、問題は、recvdatabff)によって受信されたデータチャンクを事前に割り当てられたバッファ(htmlbff)に格納する方法がわからないことです。

次のコードを検討してください(これをかなり削除したので、基本的なものだけが含まれています。たとえば、メモリの再割り当てやリーク保護などは含まれていません)。

#define BUFFERSIZE 4096
#define MAXDATASIZE 256

char *htmlbff, databff[MAXDATASIZE];
int c, i = BUFFERSIZE, q = 0;          
if(!(htmlbff = malloc(i)))
{
    printf("\nError! Memory allocation failed!");
    return 0x00;
}
while((c = recv(sock, databff, MAXDATASIZE, 0)) > 0)
{
     /*memory checks stripped out since they are irrelevent for this post*/
     /*store data to the appropriate area in htmlbff*/
     q += c;           
}

したがって(私がこれを正しく行っていて、物事が思ったとおりに進んでいる場合)cは、現在のデータチャンクのサイズであり、qこれまでに受信したデータの合計量です(ループが繰り返されるたびにq増分されます)。c現在、私はメモリ処理に使用qしています(誰かが疑問に思っている場合に備えて)が、この問題の解決にも目的があると思います。

とにかく、私が尋ねている質問は、2番目のコメントに関するものです。htmlbffrecvからのデータを正しく保存するにはどうすればよいですか?

4

4 に答える 4

5

memcpy()にデータをコピー(追加)するために使用しhtmlbffますが、のサイズを超えないようにする必要もありますhtmlbffBUFFERSIZEバイトが受信されたらデータの受信を停止するか、を使用してより多くのデータを含めるようrealloc()に拡張します。htmlbff

例えば:

char* htmlbff;
size_t htmlbff_size = BUFFERSIZE;
htmlbff = malloc(htmlbff_size);

if (htmlbff)
{
    while((c = recv(sock, databff, MAXDATASIZE, 0)) > 0)
    {
        if (c + q > htmlbff_size)
        {
            htmlbff_size *= 2; /* Arbitrary doubling of size. */
            char* tmp = realloc(htmlbff, htmlbff_size);
            if (tmp)
            {
                htmlbff = tmp;
            }
            else
            {
                /* memory allocation failure. */
                free(htmlbff);
                htmlbff = 0;
                break;
            }
        }
        memcpy(htmlbff + q, databff, c);
        q += c;
    }
}
于 2012-08-24T15:50:44.327 に答える
2

さらに処理を行う必要がない限り、私が行うのはrecv()データを直接に入れることです。htmlbff

常に別の余地があるように、realloc() htmlbffi - q未満であることを確認してください。MAXDATASIZErecv()

それからあなたは電話しますrecv(sock, htmlbff + q, MAXDATASIZE, 0)

于 2012-08-24T15:51:23.750 に答える
2

を使用memcpyし、次のようにオフセットhtmlbffqます。

memcpy(htmlbff + q, databff, c);

同様にrecv直接htmlbff:に入ることができます

c = recv(sock, htmlbff + q, MAXDATASIZE, 0));

ただし、別のバッファを保持することは問題ありません。完全なコードによっては、状況がより明確になる場合があります。

BUFFERSIZEの境界を超えてコピーしないように、必ずチェックを追加してくださいhtmlbff。処理を取り除いたとおっしゃってreallocいたので、すでに処理しているのかもしれません。

あなたの定数名は少し紛らわしいです。データをバッファリングするときにBUFFERSIZE、各チャンクのサイズ、つまりのサイズを示すために使用しますdatabff

于 2012-08-24T15:48:10.153 に答える
1

すべてのデータに合わせてバッファを再割り当て/拡張し続ける必要があります(ソケットから読み取られたデータがMAXDATASIZEを超える場合)=このように、recvがデータ​​をdatabffに読み取ると、htmlbffがメモリ内で大きくなり、新しい読み取りを追加できます。全体的なhtmlbffに。

qとcはカーソルのようなもので、どこまで進んでいるか、どこまで行かなければならないかを追跡します。

memcpy(htmlbff+q, databff, c); //Do this in your whle loop to append the data
于 2012-08-24T15:51:09.513 に答える