Having trouble programming streams

2019-01-27 04:57发布

So here's the issue: The stream isn't writing at the right time and is unable to get a response from my server. I know I'm writing the right data, because when I stop the build, it writes to the server and the server is happy. I'm confused to as why this isn't happening at the right time.

I'm using GCDAsyncSocket to read/write to the socket

I've made a separate class to handle all networking, here's my code:

-(id)init{
    self = [super init];
    if (self) {
        asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self         delegateQueue:dispatch_get_main_queue()];

        NSError *error = nil;
        if (![asyncSocket connectToHost:@"localhost" onPort:8888 error:&error]) //     Asynchronous!
        {
            // If there was an error, it's likely something like "already connected" or     "no delegate set"
            NSLog(@"I goofed: %@", error);
        }
    }
    return self;
}
//GCD Async Delegate Methods
- (void)socket:(GCDAsyncSocket *)sender didConnectToHost:(NSString *)host port:(UInt16)port
{
    NSLog(@"socket:%p didConnectToHost:%@ port:%hu", sender, host, port);
    NSLog(@"Cool, I'm connected! That was easy.");
}
 - (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
{
    if (tag == 1)
        NSLog(@"First request sent");
    else if (tag == 2)
        NSLog(@"Second request sent");
    //read data of custom length
    /*
     if (tag == TAG_FIXED_LENGTH_HEADER)
     {
     int bodyLength = [self parseHeader:data];
     [socket readDataToLength:bodyLength withTimeout:-1 tag:TAG_RESPONSE_BODY];
     }
     else if (tag == TAG_RESPONSE_BODY)
     {
     // Process the response
     [self handleResponseBody:data];

     // Start reading the next response
     [socket readDataToLength:headerLength withTimeout:-1 tag:TAG_FIXED_LENGTH_HEADER];
     }
     */
}

-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    NSError *error;
    serverJSONResponseParsed = [NSJSONSerialization JSONObjectWithData:data     options:kNilOptions error:&error];
}

-(BOOL)sendString:(NSString *)sendString{

    NSError *error;

    NSLog(@"Sending String: %@",sendString);

    NSDictionary *blobData = [NSDictionary dictionaryWithObjectsAndKeys:
                              sendString,@"string",
                              nil];
    NSString *blobString = [[NSString alloc]
                             initWithData:[NSJSONSerialization dataWithJSONObject:blobData      options:kNilOptions error:&error]
                             encoding:NSUTF8StringEncoding];
    NSLog(@"Blob Created: %@", blobString);
    NSDictionary *requestData = [NSDictionary dictionaryWithObjectsAndKeys:
                                 @"send_string",@"request_type",
                                  [NSNumber numberWithInt:0],@"security_level",
                                  @"ios",@"device_type",
                                  //No Email Provided, This is just for testing
                                 blobString,@"blob",
                                 nil];

    NSData *JSONRequestData = NULL;
    JSONRequestData = [NSJSONSerialization dataWithJSONObject:requestData options:kNilOptions error:&error];
            NSLog(@"Contents of JSONRequestData: %@",[[NSString alloc]     initWithData:JSONRequestData encoding:NSUTF8StringEncoding]);
     //Write the data
    [asyncSocket writeData:JSONRequestData withTimeout:-1 tag:1];

    //read a response
     [asyncSocket readDataToData:[GCDAsyncSocket CRLFData] withTimeout:-1 tag:2];

    NSDictionary *JSONResponseData = serverJSONResponseParsed;
    /*
    if (serverResponse != NULL) {
         JSONResponseData = [NSJSONSerialization JSONObjectWithData:serverResponse      options:kNilOptions error:&error];
    }
     */
    NSString *failure = [JSONResponseData objectForKey:@"failure"];
    if ([failure respondsToSelector:@selector(isEqualToString:)]) {
        NSLog(@"Unknown Object, Not a NSString");
    }
     if ([failure isEqualToString:@"none"]) {
        NSLog(@"Success Sending String");
        return TRUE;
    }
    else {
        NSLog(@"%@",failure);
        return FALSE;
     }

}

Here's what the console says:

2012-08-16 18:15:27.831 FlokMobile[4257:c07] Sending String: hello
2012-08-16 18:15:27.832 FlokMobile[4257:c07] Blob Created: {"string":"hello"}
2012-08-16 18:15:27.832 FlokMobile[4257:c07] Contents of JSONRequestData:     {"security_level":0,"request_type":"send_string","device_type":"ios","blob":"     {\"string\":\"hello\"}"}
2012-08-16 18:15:27.833 FlokMobile[4257:c07] (null)
2012-08-16 18:15:27.833 FlokMobile[4257:c07] It didn't work - appdel
2012-08-16 18:15:27.850 FlokMobile[4257:c07] socket:0x6992890 didConnectToHost:127.0.0.1 port:8888
2012-08-16 18:15:27.850 FlokMobile[4257:c07] Cool, I'm connected! That was easy.
2012-08-16 18:15:27.851 FlokMobile[4257:c07] First request sent

2条回答
劫难
2楼-- · 2019-01-27 05:10

When sending short chunks of data always flush the buffer after each write which you want to have an immediate effect.
I don't see you doing that in your code.
If you don't do it then the buffer will be flushed only when it is full or the stream is closed.

查看更多
闹够了就滚
3楼-- · 2019-01-27 05:11

You are reading with this:      

[asyncSocket readDataToData:[GCDAsyncSocket CRLFData] withTimeout:-1 tag:2];

Which expects a CRLF as a separator of the stream. But I don't see where you append it to your JSONRequestData. So modifying your JSONRequestData to be mutable, like so:

NSMutableData *JSONRequestData;

And then before this line:

 

[asyncSocket writeData:JSONRequestData withTimeout:-1 tag:1];

Add this:

[JSONRequestData appendData:[GCDAsyncSocket CRLFData]];
查看更多
登录 后发表回答