Search code examples
javaandroidsocketsdatainputstream

How to read a DataInputStream twice or more than twice?


I have a Socket connection to an application that I hosted elsewhere. Once I connected I made a OutputStream and DataInputStream.

Once the connection has been made, I use the OutputStream to send out a handshake packet to the application. Once this handshake has been approved, it returns a packet through the DataInputStream (1).

This packet is processed and is returned to the application with the OutputStream.

If this returned data is valid, I get another packet from the DataInputStream (2). However, I have not been able to read this packet through the DataInputStream.

I have tried to use DataInputStream.markSupported() and DataInputStream.mark() but this gave me nothing (except for an empty Exception message).

Is it possible to read the input stream for a second time? And if so, can someone please point me out what I'm doing wrong here?

EDIT: Here is my solution:

// First define the Output and Input streams.
OutputStream output = socket.getOutputStream();
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());

// Send the first packet to the application.
output.write("test"); // (not actual data that I sent)

// Make an empty byte array and fill it with the first response from the application.
byte[] incoming = new byte[200];
bis.read(incoming); //First packet receive

//Send a second packet to the application.
output.write("test2"); // (not actual data that I sent)

// Mark the Input stream to the length of the first response and reset the stream.
bis.mark(incoming.length);
bis.reset();

// Create a second empty byte array and fill it with the second response from the application.
byte[] incoming2 = new byte[200];
bis.read(incoming2);

I'm not sure if this is the most correct way to do this, but this way it worked for me.


Solution

  • I would use ByteArrayInput stream or something that you can reset. That would involve reading the data into another type of input stream and then creating one.

    InputStream has a markSupported() method that you could check on the original and the byte array one to find one that the mark will work with:

    https://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#markSupported() https://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayInputStream.html