2

ソケットを使用してHTTPGETリクエストを使用してファイルを取得するCプログラムに取り組んでいます。この関数を使用recvしてバッファーに書き込み、バッファーの内容を含む新しいファイルを追加します。プログラムは、1つの問題を除いて正常に動作します。すべてのファイルの先頭にHTTP応答が含まれています。

たとえば、プログラムを使用してWebからPDFファイルを正常にダウンロードして開くことができ、問題なく開くことができます。ただし、Notepad ++でPDFを編集すると、上部に次のように表示されます。

HTTP/1.1 200 OK
Date: Wed, 07 Nov 2012 19:57:54 GMT
Server: Apache/2.2.21 (Unix) mod_python/3.3.1 Python/2.6.6 PHP/5.3.8
Last-Modified: Wed, 01 Aug 2012 21:31:31 GMT
ETag: "f2ae8c-4134aa-4c63b04c07df2"
Accept-Ranges: bytes
Content-Length: 4273322
Content-Type: application/pdf

%PDF-1.4
%äðíø
10 0 obj
<</Filter/FlateDecode/Length 2722>>
...

ブラウザを使用してPDFファイルをダウンロードすると、プログラムによって取得されたファイルの上部にあるHTML応答を除いて、ファイルは一致します。問題のある行を削除し、ファイルハッシュを比較することで、これを確認しました。

これに取り組むには、もっとエレガントで適切な方法があると思います。HTTP応答の後、ファイルが始まる前に常に2つの改行文字があることを知っているので、応答を抽出するための私の(ずさんな、機能しない)試みは次のとおりです。

FILE* ptr_file = fopen("PDF_TEST.pdf", "w+");
char* buffer[BUFFER_SIZE];
int file_pos   = 0;
int bytes_rcvd = 0;
int first_iter = 1;

while((bytes_rcvd = recv(socket_server, buffer, BUFFER_SIZE, 0)) > 0)
{
    if(first_iter)
    {// Need to remove the HTTP response from the buffer
        char* str_buffer;
        char* html_resp = strstr(buffer, "\n\n");
        int   html_resp_length = strlen(html_resp) + 2;
        printf("HTML RESPONSE:\n%s\n\n", html_resp);
        char* first_buffer[BUFFER_SIZE - html_resp_length];
        memcpy(first_buffer, buffer+html_resp_length-1, sizeof(first_buffer));
        printf("\n\nREST OF BUFFER:%s\n", first_buffer);
        bytes_rcvd -= html_resp_length;
        fwrite(first_buffer, 1, bytes_rcvd, ptr_file);
        first_iter = 0;
        continue;
    }           
    fwrite(buffer, 1, bytes_rcvd, ptr_file); 
    file_pos += bytes_rcvd;
}  

このコードでセグメンテーション違反が発生しますが、これはバッファがの配列であり、配列のchar*場合と同じように使用しているためだと思いcharます。

私の質問:
1。)HTTP応答をファイルから分離する最良の方法は何ですか?
2.)Content-Lengthファイルへの書き込みにはHTML応答で指定されたものを使用する方が良いですか、それとも受信したバイト数を書き込む現在の方法を使用する必要がありますか?

どんな入力でも大歓迎です。

4

2 に答える 2

3

1つの方法は、2つのループを作成することです。最初のループは応答ヘッダー用で、空の行が表示されるまで読み取ります。データの2番目の受信ループ。

于 2012-11-08T16:54:15.060 に答える
2

str*バッファがnullで終了していると想定しているため、関数呼び出しで問題が発生していると思います。テストを実行する前にBUFFER_SIZE - 1、バイトを受け取って設定することができます。buffer[bytes_recvd] = '\0'

また、他の人が指摘しているように、ヘッダーの終了としてでは"\r\n\r\n"なく、探す必要があります。"\n\n"

CR LF CR LFシーケンスが2つの異なるrecv()呼び出しと交差する状態を処理するように注意してください。この可能性に対する1つの可能な回避策は、の最後の3バイトbufferをの先頭にコピーしbuffer、次の読み取りをで開始すること&buffer[3]です。

于 2012-11-08T18:50:15.127 に答える