Java Socket reading large data encounters intermittent error
I am developing an application to communicate with a third party application through socket. Basically, my application needs to send some requests to the server, and the server returns some data. When the server sends me back small amount of data, everything works well. But, when I request large amount data from server, my application sometimes doesn't receive complete data and it happens intermittently.
I've done some research on internet and followed the socket programming examples that I found but still, I couldn't solve the issue. Below is my current implementation.
BufferedInputStream is = new BufferedInputStream(socket.getInputStream());
//I know the size of data that I am expecting from the server
byte[] buffer = new byte[length];
int count = 0;
int current = 0;
while(count < length) {
current = is.read(buffer, count, length - count);
if(current == -1) {
break;
} else {
count += current;
开发者_JAVA技巧 }
}
I know the size of data that I am expecting from the server. When the problem occurs, read() method returns -1 before the data is fully received from the server. I don't have any access to the server side implementation. Please advise me if I miss out anything in my code or if there is any better way to do it.
If the read method returns -1 the server has closed the socket after sending whatever it sent. Period. If you were expecting more data you were mistaken.
Possibly the server is incorrectly coded, e.g. closes its socket instead of its outermost output stream, thereby losing data. Or possibly your end is incorrect, for example by creating multiple BufferedInputStreams per socket, instead of one for the life of the socket.
Your code just replicates DataInputStream.readFully(). However what you should really be doing is processing every buffer load as received, not trying to create an arbitrarily large buffer in memory. That just wastes space and adds latency.
Your code looks basically sound. (Using a BufferedInputStream
does not improve the performance in this case. If anything, it makes it slower. However, this is unlikely to cause this problem.)
It is also possible that buffering huge amounts of stuff in memory on the client side is causing the client side to go unresponsive for long enough to cause a socket timeout. But if your file size is only a few megabytes, you can probably discount this possibility.
However, I suspect that the real problem is a socket timeout that is too small on either the client or server end. But it is very difficult to diagnose this if you have no way of accessing the server-side configs and logs.
There are some serious problems within your code:
Assuming length = 8GB
You will get a lot of problems creating a byte[] of this size.
int count
int current
this should be
long count
long current
but if you do this, the code won't compile anymore. So you have a Maximum filesize of Integer.MAX_VALUE. if you store your download to a bytearray. (Thanks to EJP)
You have to write that data to a file ore some other memory than RAM. With a 32bit JVM, you'll never create a byte[] lager than ~1,3 GB.
精彩评论