I have a very strange behaviour during writing to a socket. In my mobile client I'm using a socket which is initialized as follows:
private void initSocket()
{
socket = new Socket();
socket.connect(new InetSocketAddress(host, port));
os = new DataOutputStream(socket.getOutputStream());
is = new DataInputStream(socket.getInputStream());
}
then periodically (every 60 seconds) I read and write some data to this socket (the code here is a little bit simplified):
if(!isSocketInitialized())
{
initSocket();
}
byte[] msg = getMessage();
os.write(msg);
os.flush();
int bytesAvailable = is.available( );
if(bytesAvailable>0)
{
byte[] inputBuffer = new byte[bytesAvailable];
int numRead = is.read(inputBuffer, 0, bytesAvailable);
processServerReply(inputBuffer, numRead);
}
And it works. But... Sometimes (very infrequently, maybe 1 or 2 times per day) my server don't receive data. My client log looks like:
Written A
Written B
Written C
Written D
Written E
and so on. But on the server side it looks like:
Received A
Received E
B,C,D data records were not received, despite of fact that on the client side it looks like all data was sent without any exceptions!
Such gaps can be small (2-3 minutes) which is not very bad, but sometimes they can be very big (1-2 hours = 60-120 cycles) and it is really a problem for my customers.
I really have no idea what can be wrong. The data seems to be sent by client, but it never arrives on the server side. I've checked it also with a proxy.
I have only logs and I can't reproduce this issue (but it happens to my customer more then one time every day) and in logs sometimes I see that the connection is broken with an Exception "sendto failed: ECONNRESET (Connection reset by peer)". After that the program closes the socket, reinitializes it:
// close
is.close();
os.close();
socket.close();
// reinitialize
initSocket();
and tries to write the data again as described above. Then I see the problem: connection established, writing successful, but NO DATA arrived on the server!
May be it has something to do with ECONNRESET may be not, but I want to mention this because may be it is important.
I would be very grateful for any ideas and tips.
P.S. Maybe it plays some role: the client code runs on an Android mobile device which is moving (it is in a car). The internet connection is established through GPRS.
UPD: I can reproduce it! At least partially (the client send A,B,C,D,E and the server receives only A). It happens every time if:
The connection is established, the client reads and writes -> OK
The connection is lost (I turn off my WLAN router :)), I became IOException, I close the streams and socket -> OK
I turn on my router, the connection is back, I initialize the socket again, the program executes write() without exceptions, but... no data arrives at the server.
BTW since the connection is back again available() returns always 0.
ByteArrayOutputStream
? Something like this – SomehowDataInputStream
is for reading primitive datatypes. It isn't bound to ACK messages in any way shape or form. – Heder