UPDATE I've found that this error is related to the GZIP streams. If I remove them and just use Object streams rather than GZIP wrapped with Object streams then my issues are resolved, no exception. I have no idea why this is, if anyone can help that would be great.
I also noted while using the GZIP that the error would be very random. E.g it seemed to depend a lot on the data within the object that I was sending across the socket. Alter the object data and it would sometimes solve the issue. For example I had a user object which contained String values such as, first name, surname, phone number. If they were all set I was getting the below issue, however if I cleared them all to be empty String values then I wouldn't get the below exception. It's very bizarre to be honest
I have a client/server socket which sends object via GZIP streams. This has worked without issue in the past. However now I am seeing connection reset when sending certain data from the server back to the client.
The client connects to the server and sends a request, to which the server will reply and send back some data. I believe the error is from the server as the connection reset exception is presented on the client side.
Here is a snippet of the exception
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:168)
at com.sun.net.ssl.internal.ssl.InputRecord.readFully(InputRecord.java:293)
at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:331)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:863)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:820)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75)
It's a very strange issue because the same socket implementation is used for all client / server communication and in our test environment everything works fine. Also the same code is used successfully before the exception occurs to collect some data from the server when the client loads the application on startup.
The above information leads me to believe there could be an issue with the specific data that is being passed, although the client & server both present no exception other than the connection reset.
Looking at netstat ( netstat -anp ) while debugging I can see successful actions result in a socket in the state of "CLOSE_WAIT", however unsuccessful ones the socket just seems to disappear all together, it's not there in any state. I also note that there is a lot of RST when the connections are finished, even for sucessful cases where I don't get connection reset exception. My TCP knowledge isn't great, but I would have thought a clean connection would end with FIN rather than getting RST?
Here is an example of the code
Client:
ObjectOutputStream out = null;
ObjectInputStream ois = null;
SSLSocketFactory sf = AdminClientApplet.getSSLContext().getSocketFactory();
Socket socket = null;
DataResponse dataRes = null;
try
{
socket = sf.createSocket( server.getHost(), server.getPort() );
// Need to connect to server and send request type,
// ie what we are requesting to be sent to us
GZIPOutputStream gZipOut = new GZIPOutputStream(socket.getOutputStream());
out = new ObjectOutputStream(gZipOut);
// write our request
out.writeObject( dataReq );
out.flush();
gZipOut.finish();
InputStream in = socket.getInputStream();
GZIPInputStream gZipIn = new GZIPInputStream(in, 65536);
ois = new ObjectInputStream(gZipIn);
// read our response
dataRes = ( DataResponse )ois.readObject();
Log.CSSO.debug("Read object " + dataRes );
}
catch (IOException ie)
{
Log.GUIP.error("IOException communicating with Admin Server on "+server, ie);
}
catch ( Exception e)
{
Log.GUIP.error("Unexpected exception communicating with Admin Server on "+server, e);
}
catch (Throwable t)
{
Log.GUIP.error("Unexpected exception communicating with Admin Server on "+server, t);
}
finally
{
// now close the connection gracefully
CSSO.debug("closing socket");
try
{
if ( out != null )
out.close();
if ( ois != null )
ois.close();
if ( socket != null )
socket.close();
}
catch ( Exception e )
{
Log.CSSO.error( "Error closing socket connection during getDataFromServer()", e );
}
}
The server has already read the 'request' at this point, so this is just the part that returns the requested data to the client. Server:
Socket socket = null;
try
{
socket = request.getSocket();
socket.setTcpNoDelay(true);
Log.CSSO.debug("Opening a response output stream to socket "+socket );
gZipOut = new GZIPOutputStream(socket.getOutputStream(), 65536 );
out = new ObjectOutputStream(gZipOut);
// the actual 'data' we are going to return
obj = getObject();
Log.CSSO.debug("About to write " + obj + " to socket" + socket.getRemoteSocketAddress() );
out.writeObject( obj );
if (Log.CSSO.isDebugEnabled())
{
Log.CSSO.debug("Wrote DataResponse to socket " + obj );
}
out.flush();
gZipOut.finish();
}
catch (IOException ie)
{
Log.CSSO.error("IOException caught sending data to client", ie);
}
catch (Exception e)
{
Log.CSSO.error("Unexpected exception caught sending data to client", e);
}
finally
{
Log.CSSO.debug( "Closing socket to " + socket.getRemoteSocketAddress() );
try
{
if ( out != null ) out.close();
if ( socket != null ) socket.close();
}
catch ( IOException e )
{
Log.CSSO.error("Unexpected exception caught closing socket", e );
}
}
Log.FLOW.debug("< run");
When on debug logging the server runs all the way through to completion, without any exceptions ( so "< run" is written in the logs ). However the client errors at
ois = new ObjectInputStream(gZipIn);
The other item worth noting is that the live system, where the exception occours is running linux ( Centos ), where as I'm not able to replicate the exception on windows and it doesn't happen on Linux Mint either. I don't expect this would be the cause but just thought I should mention it.
Any help much appreciated as I'm lost as to the cause of the issue here.