0

我正在为音乐共享应用程序编写网络服务器......当我有一个大文件(即 mp3)时,这不起作用。它在 SIGPIPE 错误代码上崩溃。我发送的标题有“连接:关闭”——但我认为这会等到下载完成后关闭连接。我知道这可能应该被分叉到一个线程中,但为了测试我想让它同步工作。

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(或正确处理它们)

这有点重复,但基本上signal(SIGPIPE, SIG_IGN);在您的应用程序首次启动时使用。这将阻止 SIGPIPE 发出信号(即您的应用程序不会崩溃)。当您想在本地处理问题时,通常会这样做。您可以通过执行以下操作在本地检查:

if ([fileHandle writeData:(NSData *)headerData] > 0 &&
    [fileHandle writeData:fileData] > 0)
{
   // writes succeeded, ...
}
else
{
   // write failed for some reason
}

NSStream您还可以使用'sstreamErrorstreamStatus属性检查错误。

于 2011-11-08T23:54:42.970 回答
0

虽然你真的应该处理 SIGPIPE。但我猜你为什么得到它是因为你在发送数据之前没有检查请求方法。
下载器很可能会先发送 HEAD 请求以获取内容长度和其他信息。

当你收到一个 HEAD 请求时,你不应该调用 [fileHandle writeData:fileData]。我猜你正在使用这里的 HTTPServer 代码。如果是这样,您可以这样做:

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

除此之外,您可能还需要处理范围请求以避免 SIGPIPE。也许还有其他东西。编写一个 HTTP 服务器来服务现实世界的请求者并不容易。

于 2013-04-21T05:23:10.357 回答