1

I am trying to write a server in Java and communicate with it using an iPhone app (Objective C). The connection goes through, and I can write data to the server, but I can't read data back from the server. I get a notification that there is data to be read, but it's empty.

The Java code was taken mostly from an Oracle example.

PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String inputLine;

out.println("Hello World");

while ((inputLine = in.readLine()) != null) {
    System.out.println(inputLine);
    System.out.flush();

    out.println("test");

    if (inputLine.equals("Bye")) {
        break;
    }
}

out.close();
in.close();
socket.close();

And the Objective C client:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    [[UIApplication sharedApplication] setKeepAliveTimeout:600 handler:^(void) {
        NSLog(@"staying alive!");
        [[DABMultitaskingController sharedInstance] startTask];
    }];

    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"10.0.1.189", 4444, &readStream, &writeStream);

    NSInputStream *inputStream = (NSInputStream *)readStream;
    NSOutputStream *outputStream = (NSOutputStream *)writeStream;
    [inputStream setDelegate:self];
    [outputStream setDelegate:self];
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [inputStream open];
    [outputStream open];

    _dataToSend = [[NSData dataWithBytes:"This is a test" length:15] retain];

    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent
{
    switch (streamEvent) {
        case NSStreamEventHasBytesAvailable: {
            NSLog(@"can read: %@", theStream);

            uint8_t *buffer;
            NSUInteger length;
            [(NSInputStream *)theStream getBuffer:&buffer length:&length];
            NSData *data = [NSData dataWithBytes:buffer length:length];
            NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"bytes: %@", data);
            NSLog(@"string: %@", string);

            break;
        }
        case NSStreamEventHasSpaceAvailable: {
            NSLog(@"can write: %@", theStream);

            if (_dataToSend != nil) {
                NSLog(@"write: %@", _dataToSend);
                [(NSOutputStream *)theStream write:[_dataToSend bytes] maxLength:[_dataToSend length]];
                [_dataToSend release];
                _dataToSend = nil;
            }

            break;
        }
        case NSStreamEventOpenCompleted: {
            NSLog(@"open complete: %@", theStream);

            break;
        }
        case NSStreamEventErrorOccurred: {
            NSLog(@"error occurred: %@", theStream);

            break;
        }
        case NSStreamEventEndEncountered: {
            NSLog(@"end encountered: %@", theStream);

            break;
        }
        default:
            break;
    }
}

2 Answers 2

1

you never send a linefeed \n to the java side BufferedReader uses these as delimiters for readLine();

_dataToSend = [[NSData dataWithBytes:"This is a test\n" length:16] retain];
Sign up to request clarification or add additional context in comments.

3 Comments

That is true, but it won't be the root cause of the problem. A BufferedReader can (completely) read a data stream that doesn't end with a line separator.
seems related to stackoverflow.com/questions/4051018/… just make your own buffer and use read I guess
This didn't solve the question above, but it did make the communication more reliable.
0

Looks like I needed to use read:maxLength: instead. Works fine now.

1 Comment

where to add this as should have edited your question with answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.