iOS アプリの EPIPE に問題があり、@try/@catch/@finally ブロックでキャッチされません。どうすればこのシグナルをキャッチできますか (SIGPIPE の可能性が高い)...
特定の種類の URL を処理する「Web プロキシ」をアプリに組み込みました。このエラーの場合、リモート エンド (これもアプリ内ですが、iOS ライブラリに隠れています) がソケットの終端を閉じているようです。 . 通知が届きません (すべきですか? ここで役立つかもしれない NSFileHandle に登録する必要があるものはありますか?)。
このプロキシは、Matt Gallagher がまとめた HTTPServer (ここからHTTPRequestHandler
入手可能) に基づいています。問題は、彼がまとめたクラスのサブクラスにあります。コードは次のとおりです (このコードはstartResponse
、基本クラスのメソッドに相当します)。
-(void)proxyTS:(SSProxyTSResource *)proxyTS didReceiveResource:(NSData *)resource
{
NSLog(@"[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
CFHTTPMessageRef response =
CFHTTPMessageCreateResponse(kCFAllocatorDefault, 200, NULL, kCFHTTPVersion1_1);
CFHTTPMessageSetHeaderFieldValue(response,
(CFStringRef)@"Content-Type",
(__bridge CFStringRef)s_MIMEtype);
CFHTTPMessageSetHeaderFieldValue(response,
(CFStringRef)@"Connection",
(CFStringRef)@"close");
CFHTTPMessageSetBody(response,
(__bridge CFDataRef)resource);
CFDataRef headerData = CFHTTPMessageCopySerializedMessage(response);
@try
{
NSLog(@" -> writing %u bytes to filehandle...",[((__bridge NSData *)headerData) length]);
[self.fileHandle writeData:(__bridge NSData *)headerData];
}
@catch (NSException *exception)
{
// Ignore the exception, it normally just means the client
// closed the connection from the other end.
}
@finally
{
NSLog(@" *ding*");
CFRelease(headerData);
CFRelease(response);
[self.server closeHandler:self];
}
}
クラッシュしたときにコンソール ログに表示される内容は次のとおりです。
Jan 15 14:55:10 AWT-NoTouch-iPhone-1 Streamer[1788] <Warning>: [SSProxyTSResponseHandler proxyTS:didReceiveResource:]
Jan 15 14:55:10 iPhone-1 Streamer[1788] <Warning>: -> writing 261760 bytes to filehandle...
Jan 15 14:55:11 iPhone-1 com.apple.launchd[1] (UIKitApplication:com.XXX.Streamer[0xf58][1788]) <Warning>: (UIKitApplication:com.XXX.Streamer[0xf58]) Exited abnormally: Broken pipe: 13
もう一方の端がパイプを閉じたためにwrite()
失敗したようです。そのため、誰かがパイプが既に閉じられていることを発見してデータを書き込もうとしない方法を教えてくれれば、私のプログラムをクラッシュさせないようにすることができます。役に立った。