套接字异常 - 连接重置 - 无法复制

时间:2016-06-17 10:25:03

标签: java sockets gzipinputstream

更新我发现此错误与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上发生薄荷也。我不认为这会是原因,但我想应该提一下。

任何帮助都非常感激,因为我在这里失去了问题的原因。

0 个答案:

没有答案