Objective c 在objective c中编写Web服务器--在上载较大文件时获得SIGPIPE调用
我正在为音乐共享应用程序编写一个Web服务器。。。当我有一个大文件(如mp3)时,这不起作用。它在SIGPIPE错误代码上崩溃。我发送的头文件有“Connection:close”——但我认为这会等到下载完成后才能关闭连接。我知道这可能应该分叉成一个线程,但为了测试,我想让它同步工作Objective c 在objective c中编写Web服务器--在上载较大文件时获得SIGPIPE调用,objective-c,cocoa,sockets,sigpipe,Objective C,Cocoa,Sockets,Sigpipe,我正在为音乐共享应用程序编写一个Web服务器。。。当我有一个大文件(如mp3)时,这不起作用。它在SIGPIPE错误代码上崩溃。我发送的头文件有“Connection:close”——但我认为这会等到下载完成后才能关闭连接。我知道这可能应该分叉成一个线程,但为了测试,我想让它同步工作 NSData *fileData =[NSData dataWithContentsOfFile:filePath]; CFHTTPMessageRef response = CFHTTPMessageCreat
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.
}
web服务器必须处理客户端提前关闭连接的情况——可能是因为它有足够的连接,或者页面加载或下载被取消。即使服务器写入正确,也可能发生这种情况。您看过对话的数据包捕获了吗?您应该退房 这有点重复,但基本上使用
信号(SIGPIPE,SIG_IGN)代码>应用程序首次启动时。这将防止SIGPIPE收到信号(即,您的应用程序不会崩溃)。当您想在本地处理问题时,通常会这样做。您可以通过执行以下操作进行本地检查:
if ([fileHandle writeData:(NSData *)headerData] > 0 &&
[fileHandle writeData:fileData] > 0)
{
// writes succeeded, ...
}
else
{
// write failed for some reason
}
您还可以使用的或属性检查错误。尽管您确实应该处理SIGPIPE。但我猜您之所以得到它,是因为您在发送数据之前没有检查请求方法
下载程序很可能首先发送HEAD请求以获取内容长度和其他信息。
当您收到HEAD请求时,不应调用[fileHandle writeData:fileData]。
我猜您使用的是来自的HTTPServer代码。如果是这样,您可以这样做:
if (![requestMethod isEqualToString:@"HEAD"] && fileData)
{
[fileHandle writeData:fileData];
}
除此之外,您可能还需要处理范围请求以避免SIGPIPE。也许还有其他东西。编写一个HTTP服务器来为现实世界的请求者提供服务并不容易。我认为try-catch块应该能够处理这种情况。(编辑以包含上述代码的这一部分)SIGPIPE是unix信号,而不是异常。你必须在每个进程(你的整个应用程序)的基础上处理它,这不是你可以在本地捕捉到的东西
在这种情况下,它将作为普通写入失败返回——同样,这是每个进程的,因此需要在main
中尽早完成。fileHandle
变量是什么类型的?