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 に答える