Я пытаюсь глубже копать, используя этот пример iPhone Chart Server, и все работает должным образом.Восстановление потерянного соединения с использованием сокетов
Что я хотел узнать дальше, так это то, как восстановить, когда соединение с сервером потеряно (по какой-либо причине) во время работы приложения.
Первая проблема заключается в том, что приложение пытается открыть входные потоки вывода & одновременно, если я реализую предупреждение, я получаю его два раза. Мне удалось разрешить это, закрыв потоки, если есть ошибка.
Во-вторых, если я являюсь другим контроллером представления, и соединение потеряно, я, похоже, не могу его восстановить. Я вызываю sendSocketMessage, и если есть ошибка, чтобы попытаться использовать initNetworkCommunication, но Я получаю фатальную ошибку.
Этот второй вопрос беспокоит меня. Я добавил точку останова All Exceptions, но ничего не получил. Как я пытаюсь «проверить» это, убедившись, что сервер работает, и приложение загружается и подключается. Затем я отключу сервер, попробую несколько кликов по приложению, и я получаю предупреждение. Я включаю сервер и пытаюсь снова щелкнуть, я получаю сообщение, отправленное на сервер, но затем приложение выходит из строя без информации!
@implementation ViewController
bool connectionError = true;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)initNetworkCommunication {
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef)@"192.168.1.1", 6035, &readStream, &writeStream);
inputStream = (__bridge NSInputStream *)readStream;
outputStream = (__bridge NSOutputStream *)writeStream;
[inputStream setDelegate:self];
[outputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream open];
[outputStream open];
}
- (void)closeAll {
NSLog(@"Closing streams.");
[inputStream close];
[outputStream close];
[inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream setDelegate:nil];
[outputStream setDelegate:nil];
inputStream = nil;
outputStream = nil;
}
- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
switch (streamEvent) {
case NSStreamEventOpenCompleted:
NSLog(@"Stream opened");
break;
case NSStreamEventHasBytesAvailable:
connectionError = false;
if (theStream == inputStream) {
uint8_t buffer[1024];
long len;
NSMutableData *currentMessage;
currentMessage = [NSMutableData dataWithBytes:"" length:strlen("")];
while ([inputStream hasBytesAvailable]) {
len = [inputStream read:buffer maxLength:sizeof(buffer)];
[currentMessage appendBytes:buffer length:len];
}
NSData * nullByte = [NSMutableData dataWithLength:1];
len = currentMessage.length;
NSRange searchRange = {0, len};
for (NSRange r; (r = [currentMessage rangeOfData:nullByte options:0 range:searchRange]).length;) {
NSString * message = [[NSString alloc] initWithBytes:currentMessage.bytes length:r.location encoding:NSUTF8StringEncoding];
searchRange.location = r.location+r.length;
searchRange.length = len - searchRange.location;
[self messageReceived:message];
}
[currentMessage replaceBytesInRange:(NSRange){0, searchRange.location} withBytes:NULL length:0];
}
break;
case NSStreamEventErrorOccurred:
NSLog(@"Can not connect to the host!");
connectionError = true;
[self closeAll];
[self connectionLost];
break;
case NSStreamEventEndEncountered:
break;
default:
NSLog(@"Unknown event");
}
}
- (void) connectionLost {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Alert!"
message:@"Connection to the server lost!"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
- (void) messageReceived:(NSString *)message {
[messages addObject:message];
if (inputStream.streamStatus == NSStreamStatusClosed || inputStream.streamStatus == NSStreamStatusError || inputStream.streamStatus == NSStreamStatusNotOpen) {
[self closeAll];
[self initNetworkCommunication];
}
// do things with the message...
}
- (void) initConnection {
[self initNetworkCommunication];
messages = [[NSMutableArray alloc] init];
}
- (IBAction)joinChat:(id)sender {
[self initConnection];
[self sendSocketMessage: @"iam:" message: _inputNameField.text];
}
- (void) sendSocketMessage:(NSString*) sendCommand message:(NSString*) sendMessage
{
if (outputStream.streamStatus == NSStreamStatusClosed || outputStream.streamStatus == NSStreamStatusError || outputStream.streamStatus == NSStreamStatusNotOpen) {
[self closeAll];
[self initNetworkCommunication];
}
NSString *response = [NSString stringWithFormat: @"%@%@", sendCommand, sendMessage];
NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
[outputStream write:[data bytes] maxLength:[data length]];
NSLog(@"clint sent: %@", response);
}
@end
Я получаю ошибку это screen grab:
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
Тема 1: EXC_BAD_ACCESS (код = 1, адрес = 0x0)
Любые советы?
Это не там, где крах. Добавьте [контрольную точку исключения] (http://stackoverflow.com/questions/17802662/exception-breakpoint-in-xcode/17802723#17802723) и запустите ее снова. – rebello95
@ rebello95: Я добавил один, но все еще не больше информации ... Экран захвата [здесь] (http://tinypic.com/view.php?pic=1z57kn8&s=8#.VM5ply7L-6E) – Kostas