【问题标题】:Socket disconnection in IOSIOS中的socket断开连接
【发布时间】:2012-05-25 18:31:48
【问题描述】:

我需要 IOS Socket 编程方面的帮助。我已经在 IOS 和 Java 服务器之间实现了一个成功的 TCP Socket 连接,但是我发现在套接字失败后重新连接它是不可能的(我断开我的网络并重新连接它)。

这是我用来打开流的代码:

- (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?

提前谢谢你!!

【问题讨论】:

  • 重新连接时遇到什么错误?另外,您确定服务器正在正确侦听(例如,您可以使用 Mac 上的 netcat 连接到它,断开连接,然后立即重新连接)吗?
  • 我猜你用的是 ARC,对吧?
  • 是的,我正在使用 ARC,这就是为什么我的代码没有发布...但是我在服务器部分接收到一切正常,所以我可以在两个部分之间交换数据包...问题来了当我强制断开连接时尝试重新连接时......我已经能够再次发送但无法接收。我将提供有关我收到的套接字事件的更多信息...
  • 我在 Android 上也是这样做的,没有问题,所以我确定这是一个 IOS 问题... :S
  • 我不知道为什么在另一端没有活动服务器的情况下我可以“打开”两个套接字流......为什么会这样?之后,当我尝试在输出流上写入时被阻止...

标签: objective-c ios sockets tcp


【解决方案1】:

最后我用 CocoaAsyncSockets https://github.com/robbiehanson/CocoaAsyncSocket 实现了它,用这个套接字重新连接真的很容易。

首先我初始化socket对象:

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];
}  

我发现该库非常易于使用。我希望这对任何人都有帮助。 非常感谢。

【讨论】:

  • 很棒的框架,但在 iOS 6 上似乎没有调用 socketDidDisconnect ... :(
  • 对不起,使用 GCDAsyncSocket 时它确实有效。我使用的是 AsyncSocket...
  • 很高兴你找到了它;),它解决了我在使用其他框架时遇到的麻烦
猜你喜欢
  • 2022-07-08
  • 1970-01-01
  • 1970-01-01
  • 2011-02-03
  • 2020-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多