为什么不调用库(委托)方法? CocoaAsyncSocket

时间:2012-06-07 19:29:57

标签: iphone objective-c ios delegates cocoaasyncsocket

我已经在这个问题上坚持了几天,似乎越来越接近一个决议(在伟大的用户@ SO的帮助下)。我正在使用CocoaAsyncSocket库来创建到Windows服务器的TCP套接字连接。

我的appDelegate正在建立连接:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    socket = [[AsyncSocket alloc] initWithDelegate:self];
    NSError *error = nil;
    if (![socket connectToHost:@"199.5.83.63" onPort:11005 error:&error]) 
    {
        NSLog(@"Error connecting: %@", error);
    }

    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    // Override point for customization after application launch.
    self.viewController = [[[tekMatrixViewController alloc] initWithNibName:@"tekMatrixViewController" bundle:nil] autorelease];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

我有一个名为onSocket的连接方法(库的一部分):( AsyncSocket *)sock didConnectToHost:(NSString *)主机端口:(UInt16)端口:

- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
    NSLog(@"connected :D");
}

此方法被称为,因为我可以看到NSLOG的输出并且我已成功连接。我还可以从Windows机器上看到连接成功(使用日志文件)。

我还测试了另一个委托方法也被调用:

- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
{
    NSLog(@"error - disconnecting");
    // start reconnecting procedure here...
}

我已经测试过willDisconnectWithError方法的工作原理是在模拟器中运行我的应用程序,然后从笔记本电脑上拔下我的以太网线。一旦我这样做,我在输出中看到了“错误 - 断开连接”字符串。

然而,最大的问题是我的委托方法(同样来自库)没有被调用。

未调用委托方法:

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
    NSData *strData = [data subdataWithRange:NSMakeRange(0, [data length])];
    NSString *msg = [[NSString alloc] initWithData:strData encoding:NSUTF8StringEncoding];
    if(msg)
    {
        NSLog(@"RX:%@",msg);
    }
    else 
    {
        NSLog(@"Fail");
    }    
}

我对委托方法如何运作的知识和理解充满信心,但我仍然不太了解他们如何被调查。为了进一步复杂化并引起混淆,正在调用一个委托方法(onSocket:didConnectToHost端口:),但未调用另一个(onSocket:didReadData标记:)。不幸的是,这只是我的第一步问题,但在我遇到其他问题之前,我必须解决这个问题。

非常感谢任何帮助。谢谢:D

2 个答案:

答案 0 :(得分:5)

来自AsyncSocket.h文件:

/**
 * Called when a socket has completed reading the requested data into memory.
 * Not called if there is an error.
**/
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;

我的第一个猜测是你有一个错误,这就是为什么没有调用你的委托方法。您是否也实现了处理错误的委托方法?

/**
 * In the event of an error, the socket is closed.
 * You may call "unreadData" during this call-back to get the last bit of data off the socket.
 * When connecting, this delegate method may be called
 * before"onSocket:didAcceptNewSocket:" or "onSocket:didConnectToHost:".
**/
- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;

注意:仅仅因为您能够无错误地连接,并不意味着您将能够在没有错误发生的情况下进行读取。传递给connectToHost:onPort:error:的错误参数未涵盖所有错误情况。

编辑:您可以发布在套接字上调用其中一个“readData”方法的代码部分吗?那里可能有一些东西被忽视了。例如,如果没有“readData”消息被发送到套接字,那么这就解释了为什么没有调用你的委托方法。

编辑:只有在套接字上调用以下readData方法之一后,才会调用onSocket:didReadData:withTag:方法。例如:

// The readData and writeData methods won't block (they are asynchronous).
// 
// When a read is complete the onSocket:didReadData:withTag: delegate method is called.
// When a write is complete the onSocket:didWriteDataWithTag: delegate method is called.
// 
// You may optionally set a timeout for any read/write operation. (To not timeout, use a negative time interval.)
// If a read/write opertion times out, the corresponding "onSocket:shouldTimeout..." delegate method
// is called to optionally allow you to extend the timeout.
// Upon a timeout, the "onSocket:willDisconnectWithError:" method is called, followed by "onSocketDidDisconnect".
// 
// The tag is for your convenience.
// You can use it as an array index, step number, state id, pointer, etc.

/**
 * Reads the first available bytes that become available on the socket.
 * 
 * If the timeout value is negative, the read operation will not use a timeout.
**/
- (void)readDataWithTimeout:(NSTimeInterval)timeout tag:(long)tag;

答案 1 :(得分:0)

我的服务器应用程序通过[newSocket writeData:welcomData withTimout:-1 tag:1]发送了设置数据后,客户端应用程序中的didReadData()方法没有被调用时遇到了类似的问题。

将以下行插入didConnectToHost()方法后,我的问题已解决。 [clientAsyncSocket readDataToData:[GCDAsyncSocket CRLFData] withTimeout:-1.0 tag:0];

现在,无论何时发送内容,都将适当调用我客户的didReadData()方法。