0

私はこの方法でlibeventで(大きなファイルの)チャンク応答を実行しようとしています::

evhttp_send_reply_start(request, HTTP_OK, "OK");

int fd = open("filename", O_RDONLY);
size_t fileSize = <get_file_size>;
struct evbuffer *databuff = NULL;
for (off_t offset = 0;offset < fileSize;)
{
    databuff = evbuffer_new();

    size_t bytesLeft = fileSize - offset;
    size_t bytesToRead = bytesLeft > MAX_READ_SIZE ? MAX_READ_SIZE : bytesLeft;

    evbuffer_add_file(databuff, fd, offset, bytesToRead);
    offset += bytesToRead;

    evhttp_send_reply_chunk(request, databuff); // send it
    evbuffer_free(databuff);                    // destroy it
}

evhttp_send_reply_end(request);

fclose(fptr);

問題はこれにあります。add_fileが非同期であると感じているので、3番目かそこらevhttp_send_reply_chunkでエラー(または同様のもの)が発生します。

[警告]evhttp_send_chainClosed(45):不正なファイル記述子

チャンク転送エンコーディングを実際にテストするMAX_READ_SIZEように設定しました。8

使用できる方法があることに気づきましたが、evhttp_request_set_chunked_cb (struct evhttp_request *, void(*cb)(struct evhttp_request *, void *)) 使用方法の例が見つかりませんでした。

たとえば、コールバックに引数を渡すにはどうすればよいですか?引数は、要求ハンドラーに渡されたものと同じ引数のようですが、送信するファイル記述子とファイルオフセットを保持するオブジェクトを作成したいので、必要なものではありません。

すべての助けに感謝します。

よろしくお願いしますスリ

4

2 に答える 2

0

libevent v2のドキュメントには、非同期であるとは記載されていませんが、コードで考慮されていないファイル記述子を閉じると記載されています。

int fd = open("filename", O_RDONLY);私はあなたがあなたのループの中に移動する必要があると信じています。

文字列バッファを最初から作成するだけで、ファイルコードの外部でチャンク処理をテストすることもできます。

それを除けば、(そしてあなたの例であるはずの最後の行fclose(fp);は正しいように見えます

于 2010-03-21T22:49:24.200 に答える
0

ナイスナイスメイト。ありがとうございます。転送をチャンクにしたい唯一の理由は、バッファの読み取りを避けるためであることに気付きました。しかし、evbuffer_add_file はすでに sendfile を使用しているため (見つかった場合)、これは実際には問題になりません。

そこで、ループを完全に削除して試しました。しかし、コンテンツはまだ送信されていません。しかし、少なくとも今回は、不正なファイル記述子エラーは発生していません (その通りです。これは、ファイルが閉じられたためでした。ファイル ハンドルのチェックでこれが確認されました!)。

于 2010-03-24T19:03:06.663 に答える