1

我已经在这个问题上停留了几天,似乎越来越接近解决方案(在伟大的用户@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 *)host port:(UInt16)port 的连接方法(库的一部分):

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

4

2 回答 2

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”消息被发送到套接字,那么这将解释为什么没有调用您的委托方法。

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

// 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;
于 2012-06-07T19:41:18.247 回答
0

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

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

现在,每当发送内容时,都会适当地调用我客户的 didReadData() 方法。

于 2019-12-10T01:12:34.983 回答