Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 在objective c中编写Web服务器--在上载较大文件时获得SIGPIPE调用_Objective C_Cocoa_Sockets_Sigpipe - Fatal编程技术网

Objective c 在objective c中编写Web服务器--在上载较大文件时获得SIGPIPE调用

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

我正在为音乐共享应用程序编写一个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.
}

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
变量是什么类型的?