InputStream.read sometimes stops reading

Viewed 595

My App should be able to receive messages from a server using Stream-class.

My code is:

var inputStream  : InputStream? = nil
var outputStream : OutputStream? = nil

...

func establishConnection() {
    ...
    Stream.getStreamsToHost(withName: "app.mybusiness.com", port: port, inputStream: &self.inputStream, outputStream: &self.outputStream)
    ...
}

func stream(_ someStream: Stream, handle eventCode: Stream.Event) {

    switch eventCode {
        case Stream.Event.hasBytesAvailable:
        var output = ""

        var buffer = [UInt8](repeating: 0, count: 1024)

        while (self.inputStream!.hasBytesAvailable){

            let bytesRead:Int=inputStream!.read(&buffer, maxLength: buffer.count)

            if (bytesRead > 0) { // had here (bytesRead >= 0) too
                output += NSString(bytes: UnsafePointer(buffer), length: bytesRead, encoding:String.Encoding.utf8.rawValue)! as String
            } else {
                print("# error")
            }
            print("> \(output)")
        }

        // Now do something with the data we got
        HelpMethods.pushServerIncoming(inString: output)

       default:
           ...
    }

}

So this works quite nice, but sometimes it seems to stop receiving data.
It reads the first 1024 bytes, then the second 1024 and instead of continuing (about 3 or 4 more iterations are necessary to get the whole message) it reads only a few more bytes and then inputStream.hasBytesAvailable returns false.

It would be easy to say: Ahh thats the fault of the server, but this problem does not occur within the android-version of the app.

I tried to change buffer-size (from 1 to 4096) but it doesn't change anything. With 4096 bytes I had a case where the stream reads only a few hundred bytes in the first run and then said: all done buddy! nothing more to read ...

The behavior is not predictable. Tested it with the same message a lot of times and it worked, worked, worked, did not work, ...

Any suggestions?

1 Answers

To avoid hanging or crashing of Inputstream reader You can first read the InputStream to a String...

String myString = "Hello there how are you";
InputStream inputStream = new ByteArrayInputStream(myString .getBytes(StandardCharsets.UTF_8));

If reading from a socket...

String myString = socket.getInputStream().toString();  //if reading socket

Then you can assign the Inputstream variable...

InputStream inputStream = new ByteArrayInputStream(myString .getBytes(StandardCharsets.UTF_8));
Related