Yi Jiang
Yi Jiang

Reputation: 4028

How to make my Thread waiting until GCDAsyncSocket or AsyncSocket response me?

When I finding TCP/IP communication lib for Objective-C, people suggested me to use GCDAsyncSocket. I have tired it, I can use GCDAsyncSocket to establish TCP connection, and send packets.

But, my project has a list of process. I have to wait connection established, then send IP packet 1, read response data, send IP packet 2, read response data...... like following code:

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

I have to wait IP Delegate Function return me something.

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

}

Question:

How to make my thread waiting for GCDAsyncSocket response? Or is there other solution? Like replace GCDAsyncSocket or AsyncSocket by something else?

Upvotes: 1

Views: 1084

Answers (1)

Yi Jiang
Yi Jiang

Reputation: 4028

I found the solution. I know it is not good enough, but this is only way I found to solve my problem:

in .h file.

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

in .m file

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

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

For 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;

}

Upvotes: 1

Related Questions