Question

I am having a socket listener program running(eclipse) on a mac machine and iOS client app is sending image to it in Bytes format. Normally, Image bytes will be 40 K and above. I am facing a strange issue while reading the image bytes in socket. I have checked many links, they are suggesting to use like below code for reading all the bytes. The issue is, its reading all the bytes and NOT coming out of 'While' loop. After reading all the bytes, just struck inside the while loop only. I don't know what to do? Could someone please help me to solve this issue?

InputStream input = socket.getInputStream();

ByteArrayOutputStream baos = new ByteArrayOutputStream();    
byte[] bufferr = new byte[1024];
int read = 0;
long numWritten = 0;
try { 
    // Tried both the below while conditions, both are giving same issue     
    // while ((read = input.read(bufferr, 0, bufferr.length)) != -1) 

    while ((read = input.read(bufferr)) > 0) {
        baos.write(bufferr, 0, read);

        numWritten += read;
        System.out.println("numWritten: " + numWritten);      
    }
} catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
}  
try {
    baos.flush();
} catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
}   
byte[] data = baos.toByteArray();

The below is my iOS code. I am closing the stream, still the same issue.

    -(void) shareImage
{
    AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
    UIGraphicsBeginImageContext(appDelegate.window.bounds.size);
    [appDelegate.window.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    NSData * data = UIImagePNGRepresentation(image);
    //[data writeToFile:@"screenshot.png" atomically:YES];

    NSLog(@"[data length] %i: ", [data length]);
    self.sentPing = YES;

    int num = [self.outputStream write:[data bytes] maxLength:([data length])];
    if (-1 == num) {
        NSLog(@"Error writing to stream %@: %@", self.outputStream, [self.outputStream streamError]);
    }else{
        NSLog(@"Wrote %i bytes to stream %@.", num, self.outputStream);
        [self.outputStream close];

        //NSTimer *myRegularTime = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(ShareNextScreen:) userInfo:nil repeats:NO];
    }

}
Was it helpful?

Solution

input.read(buffer) will block until data is received. If the stream is closed, it will return -1 as you are testing for. But, since the stream is still open and is waiting for data to arrive, it'll block.

Since you did update your question, I will update my answer. Closing a stream is not the same as terminating a TCP session.

Closing a stream will put the connection into FIN_WAIT_1 or FIN_WAIT_2 and it needs to finish and reset to be fully closed. You need to tell your server that you're shutting down your client and then shut down, or tell the client you're shutting down the server, and then close. Basically, both sides need to close when they wish to terminate the connection. Closing also may, depending on your environment, not even do anything but release references.

In most implementations of low level socket APIs, you have socket_shutdown(2) which actually sends the FIN TCP packet for a mutual shutdown initiation.

Basically both parties need to close, or the connection will be stuck in a waiting state. This is a defined behavior in various RFCs. An explanation can be found here.

From the post I linked, you can review the diagram here.

OTHER TIPS

You are reading to end of stream but the peer hasn't closed the connection. So, you block.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top