1

当我为 Objective-C 找到 TCP/IP 通信库时,人们建议我使用 GCDAsyncSocket。累了,可以用GCDAsyncSocket建立TCP连接,发送数据包。

但是,我的项目有一个过程列表。我必须等待连接建立,然后发送 IP 包 1,读取响应数据,发送 IP 包 2,读取响应数据......如下代码:

    [self establishGCDAsyncSocketTCPConnection];

    if ([self handshake1]) {
        NSLog(@"handshake 1 is DONE! ");
    } else {
        NSLog(@"handshake 1 is FAIL! *");
        return NO;
    }

    if ([self handshake2]) {
        NSLog(@"handshake 2 is DONE! ");
    } else {
        NSLog(@"handshake 2 is FAIL! *");
        return NO;
    }

我必须等待 IP 委托函数返回给我一些东西。

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

    tcpConnectionFlag = YES;
}


- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
    //return me something.

}

问题:

如何让我的线程等待 GCDAsyncSocket 响应?还是有其他解决方案?就像用其他东西替换 GCDAsyncSocket 或 AsyncSocket 一样?

4

1 回答 1

1

我找到了解决方案。我知道这还不够好,但这是我发现解决问题的唯一方法:

在 .h 文件中。

@interface IPEngine : NSObject{
    NSOperationQueue *operationQueue;
}
@property (nonatomic, retain) NSOperationQueue *operationQueue;

在 .m 文件中

-(NSData *) sendIpPacket:(NSData *)data {
    switch (protocolType) {
        case TCPCommunication:
            [gcdAsyncTCPSocket writeData:data
                             withTimeout:-1.0
                                     tag:0];
            break;
        case UDPCommunication:{

            [gcdAsyncUdpSocket sendData:data
                                 toHost:ipAddressString
                                   port:[ipPortString integerValue]
                            withTimeout:3
                                    tag:0];
            }
            break;

        default:
            break;
    }
    [self waitForResponse];
    return responseData;
}

-(void) waitForResponse
{
    self.operationQueue = [NSOperationQueue new];
    self.operationQueue.suspended=true; //Okay make true
    [self.operationQueue addOperationWithBlock:^{}];
    [self.operationQueue waitUntilAllOperationsAreFinished];
}

对于 TCP

#pragma mark GCDAsyncSocket Delegate for TCP
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
    self.operationQueue.suspended = NO;
}

- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
{
    self.operationQueue.suspended = YES;
}

- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
    responseData = data;
    self.operationQueue.suspended = NO;
}

- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
    self.operationQueue.suspended = NO;
}

对于 UDP

#pragma mark GCDAsyncUdpSocket Delegate for UDP
/**
 * Called when the datagram with the given tag has been sent.
 **/
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didSendDataWithTag:(long)tag{
    self.operationQueue.suspended = YES;
}

/**
 * Called if an error occurs while trying to send a datagram.
 * This could be due to a timeout, or something more serious such as the data being too large to fit in a sigle packet.
 **/
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError *)error{
    self.operationQueue.suspended = NO;
}

/**
 * Called when the socket has received the requested datagram.
 **/
- (void)udpSocket:(GCDAsyncUdpSocket *)sock
   didReceiveData:(NSData *)data
      fromAddress:(NSData *)address
withFilterContext:(id)filterContext{
    responseData = data;
    self.operationQueue.suspended = NO;
}

/**
 * Called when the socket is closed.
 **/
- (void)udpSocketDidClose:(GCDAsyncUdpSocket *)sock withError:(NSError *)error{
    self.operationQueue.suspended = NO;

}
于 2013-12-04T00:23:20.347 回答