Jisan Mahmud
Jisan Mahmud

Reputation: 201

JAVA : BufferdInputStream and BufferedOutputStream

I have several questions-

1. I have two computers connected by socket connection. When the program executes

outputStream.writeInt(value);
outputStream.flush();

what actually happens? Does the program wait until the other computer reads the integer value?

2. How can I empty the outputStream or inputStream? Meaning, when emptying the outputStream or inputStream, whatever is written to that stream gets removed. (please don't suggest to do it by closing the connection!) I tried to empty the inputStream this way-

byte[] eatup=new byte[20*1024];
int available=0;
while(true)
{
    available=serverInputStream.available();
    if(available==0)
       break;
    serverInputStream.read(eatup,0,available);
}
eatup=null;

String fileName=(String)serverInputStream.readObject();

Program should not process the line as nothing else is being written on the outputStream . But my program executes it anyway and throws a java.io.OptionalDataException error.

Note: I am working on a client-server file transfer project. The client sends files to the server. The second code is for server terminal. If 'cancel button' is pressed on server end then it stops reading bytes from the serverInputStream and sends a signal(I used int -1) to the client. When client receieves this signal it stops sending data to the server, but I've noticed that serverInputStream is not empty. So I need to empty this serverInputStream so that the client computer is able to send the server computer files again(That's why I can't manage a lock from read method)

Upvotes: 2

Views: 535

Answers (1)

Mike Q
Mike Q

Reputation: 23219

1 - No. On the flush() the data will be written to the OS kernel which will likely immediately hand it to the network card driver, which in turn will send it to the receiving end. In a nutshell the send is fire and forget.

2 - As Jeffrey commented available() is not reliable for this sort of operation. If doing blocking IO then as he suggests you should just use read() speculatively. However it should be said that you really need to define a protocol on top of the raw streams, even if it's just using DataInput/DataOutputStream. When using raw write/read the golden rule is one write != one read. For example if you were to write 10 bytes on one side and had a reading loop on the other there is no guarantee that one read will read all 10 bytes. It may be "read" as any combination of chunks. Similarly two writes of 10 bytes might appear as one read of 20 bytes on the receiving side. Put another way there is no concept of a "packet" unless you create a higher level protocol on top of the raw bytes to do packets. An example would be each send is prefixed by a byte length so the receiving side knows how much data to expect in the current packet.

If you do need to do anything more complicated than a basic apps I strongly encourage you to investigate some higher level libraries that have solved many of the gnarly issues of network IO. I would recommend Netty which I use for production apps. However it is quite a big leap in understanding from a simple IO stream to Netty's more event based system. There may be other libraries somewhere in the middle.

Upvotes: 2

Related Questions