2012-05-25 5 views
1

Мне нужна помощь в программировании сокета IOS. Я реализовал успешное соединение TCP Socket между IOS и Java-сервером, однако я обнаружил, что невозможно повторно подключить его после сбоя сокета (я отключу свою сеть и снова подключу его).Разъединение разъема в IOS

Вот код я использую, чтобы открыть потоки:

- (void)initCommunication{ 
@try { 
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"XXX.XXX.XXX.XXX", 4454, &readStream, &writeStream); 

    inputStream = (__bridge NSInputStream *)readStream; 
    outputStream = (__bridge NSOutputStream *)writeStream; 

    //Asignamos los delegates 
    inputStream.delegate = self; 
    outputStream.delegate = self; 

    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 

    [inputStream open]; 
    [outputStream open]; 
    connected = true; 
    } 
} 
@catch (NSException *exception) { 
    connected = false; 
    NSLog(@"Error connecting socket: %@", exception.reason); 
    [self checkConnection]; 
} 
} 

И когда я получаю NSStreamEventErrorOccurred или NSStreamEventEndEncountered я стараюсь, чтобы закрыть соединение и снова подключите.

Я закрываю его:

-(void) close{ 

[inputStream close]; 
[inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
[outputStream close]; 
[outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
[inputStream setDelegate:nil]; 
inputStream = nil; 
[outputStream setDelegate:nil]; 
outputStream = nil; 

connected = false; 
} 

Проблема в том, что розетка не переподключения снова ... Я имею в виду, об использовании SmallSockets или CocoaAsyncSockets, чтобы увидеть, если я могу восстановить гнездо ... У вас см. любую проблему реализации? Вы рекомендуете использовать SmallSockets или CocoaAsyncSockets?

Благодарим вас заранее!

+1

Какая ошибка возникает при повторном подключении? Кроме того, вы уверены, что сервер правильно прослушивает (например, вы можете подключиться к нему с netcat с вашего Mac, отключить и сразу же подключиться)? – abarnert

+0

Я предполагаю, что вы используете ARC, верно? – parselmouth

+0

Да, я использую ARC, поэтому в моем коде нет релизов ... однако я получаю все нормально на части сервера, поэтому я могу обмениваться пакетами между обеими частями ... проблема возникает, когда я пытаюсь восстановить соединение, когда я заставить отключить ... Я смог отправить снова, но не получать. Я добавлю дополнительную информацию о событиях сокетов, которые я получаю ... – Kasas

ответ

3

Наконец-то я реализовал его с CocoaAsyncSockets https://github.com/robbiehanson/CocoaAsyncSocket, и было действительно легко сделать пересоединение с этим сокетом.

Сначала я инициализировать объект сокета:

socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()]; 

Для подключения я использую:

NSError *err = nil; 
if ([socket connectToHost:@"XXX.XXX.XXX.XXX" onPort:YYYY error:&err]) 
{ 
NSLog(@"Connection performed!"); 
} 
else 
{ 
NSLog(@"Unable to connect: %@", err); 
} 

И тогда вы можете использовать делегат сделать переподключение всякий раз, когда это не удалось:

- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port 
{ 
NSLog(@"Socket:DidConnectToHost: %@ Port: %hu", host, port); 

connected = YES; 
    [sock readDataWithTimeout:-1 tag:0]; 
} 

- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err 
{ 
NSLog(@"SocketDidDisconnect:WithError: %@", err); 
    connected = NO; 
    //We will try to reconnect 
    [self checkConnection]; 
} 

- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag 
{ 
    [self processReceivedData:data]; 
    [sock readDataWithTimeout:-1 tag:0]; 
} 

Мне очень понравилась эта библиотека. Надеюсь, это поможет кому угодно. Большое спасибо.

+0

Отличная инфраструктура, но socketDidDisconnect, похоже, не вызывается на iOS 6 ... :( –

+0

Извините, он работает при использовании GCDAsyncSocket. Вместо этого я использовал AsyncSocket ... –

+0

Рад, что вы его нашли;), он разрешил мои проблемы с другими фреймами – Kasas

Смежные вопросы