0

音楽共有アプリ用の Web サーバーを作成しています...大きなファイル (つまり mp3) がある場合、これは機能しません。SIGPIPE エラー コードでクラッシュします。送信しているヘッダーには「Connection: close」がありますが、これはダウンロードが終了して接続が閉じるまで待機すると想定していました。これはおそらくスレッドに分岐する必要があることはわかっていますが、テストのために同期的に動作させたいと考えています。

NSData *fileData =[NSData dataWithContentsOfFile:filePath];

CFHTTPMessageRef response =
CFHTTPMessageCreateResponse(
                            kCFAllocatorDefault, 200, NULL, kCFHTTPVersion1_1);
CFHTTPMessageSetHeaderFieldValue(
                                 response, (CFStringRef)@"Content-Type", (CFStringRef)@"audio/mpeg");
CFHTTPMessageSetHeaderFieldValue(
                                 response, (CFStringRef)@"Connection", (CFStringRef)@"close");
CFHTTPMessageSetHeaderFieldValue(
                                 response,
                                 (CFStringRef)@"Content-Length",
                                 (CFStringRef)[NSString stringWithFormat:@"%ld", [fileData length]]);
CFDataRef headerData = CFHTTPMessageCopySerializedMessage(response);

@try
{
    [fileHandle writeData:(NSData *)headerData];
    [fileHandle writeData:fileData];
}@catch (NSException *exception)
{
    // Ignore the exception, it normally just means the client
    // closed the connection from the other end.
}
4

3 に答える 3

1

Web サーバーは、クライアントが接続を早期に閉じる場合に対処する必要があります。おそらく、十分に接続されているか、ページの読み込みまたはダウンロードがキャンセルされました。これは、サーバーが正しく作成されている場合でも発生する可能性があります。会話のパケット キャプチャを見たことがありますか?

于 2011-04-27T00:19:48.263 に答える
0

あなたは本当にSIGPIPEに対処する必要がありますが。しかし、データを送信する前にリクエストメソッドをチェックしなかったためだと思います。
ダウンローダが最初に HEAD リクエストを送信して、コンテンツの長さとその他の情報を取得する可能性は非常に高くなります。

HEAD リクエストを受け取ったら、[fileHandle writeData:fileData] を呼び出してはいけません。hereの HTTPServer コードを使用していると思います。もしそうなら、あなたはこれを行うことができます:

if (![requestMethod isEqualToString:@"HEAD"] && fileData)
{
  [fileHandle writeData:fileData];
}

それ以外にも、SIGPIPE を回避するために範囲要求に対処する必要がある場合があります。そして多分他のもの。実際のリクエスターにサービスを提供する HTTP サーバーを作成するのは簡単ではありません。

于 2013-04-21T05:23:10.357 に答える