更新我发现此错误与GZIP流有关。如果我删除它们只是使用对象流而不是使用对象流包装的GZIP,那么我的问题就解决了,没有例外。我不知道为什么会这样,如果有人能提供帮助那就太好了。
我在使用GZIP时也注意到错误是非常随机的。例如,它似乎很大程度上取决于我通过套接字发送的对象内的数据。改变对象数据,它有时会解决问题。例如,我有一个用户对象,其中包含字符串值,如名字,姓氏,电话号码。如果他们都已设置我得到了以下问题,但是如果我将它们全部清空为String值,那么我就不会得到以下异常。说实话,这很奇怪
我有一个客户端/服务器套接字,它通过GZIP流发送对象。这在过去没有问题。但是现在我在将某些数据从服务器发送回客户端时看到连接重置。
客户端连接到服务器并发送请求,服务器将回复该请求并发回一些数据。我相信错误来自服务器,因为客户端出现了连接重置异常。
以下是异常的片段
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)
这是一个非常奇怪的问题,因为相同的套接字实现用于所有客户端/服务器通信,并且在我们的测试环境中一切正常。在发生异常之前,成功使用相同的代码,以便在客户端在启动时加载应用程序时从服务器收集一些数据。
上述信息让我相信,虽然客户端和客户端正在传递特定数据,但可能存在问题。除了连接重置之外,服务器都不会出现任何异常。
在调试时查看netstat(netstat -anp)我可以看到成功的动作导致套接字处于" CLOSE_WAIT"状态,但是不成功的套接字似乎一起消失,它&#39 ;在任何州都没有。我还注意到连接完成后有很多RST,即使是在我没有获得连接重置异常的成功案例中也是如此。我的TCP知识并不是很好,但我认为干净的连接会以FIN结束而不是获得RST?
以下是代码
的示例客户端:
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 );
}
}
服务器已经阅读了'请求'此时,这只是将请求的数据返回给客户端的部分。 服务器:
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");
在进行调试日志记录时,服务器一直运行到完成,没有任何异常(因此&#34;&lt; run&#34;写入日志中)。但是
的客户端错误ois = new ObjectInputStream(gZipIn);
值得注意的另一个问题是,运行异常的实时系统正在运行linux(Centos),因为我无法在Windows上复制异常,而且它不会在Linux上发生薄荷也。我不认为这会是原因,但我想应该提一下。
任何帮助都非常感激,因为我在这里失去了问题的原因。