繁体   English   中英

客户端关闭或客户端重新启动时,Java Server套接字TCP连接处于CLOSE_WAIT状态

[英]Java Server socket TCP connection stuck in CLOSE_WAIT state while client shutdown or client restart

执行客户端重新启动或关闭时,所有套接字连接都挂在服务器端的CLOSE_WAIT中。 XdrAble用于将序列化数据发送到XDR流中。 池是标准KeyedSocketPool的对象。 MAXIMUM_RETRY,MAXIMUM_RETYR_BEFORE_RESET_POOL是为重置池连接而定义的常量。 关闭连接时我缺少什么?

公开RESP调用(REQ请求,RESP响应,整数requestLength,整数超时)引发异常{
套接字套接字= null;

IOException ioException = null;

short attempts = 0;
boolean needResetPool = false;

while (true)
{
  ioException = null;

  try
  {
    // Get socket (open if not connected)
    socket = (Socket) pool.borrowObject ();
    socket.setSoTimeout (timeOut);

    // Send request
    BufferedOutputStream outputStream = new BufferedOutputStream (socket
        .getOutputStream ());
    XdrBufferEncodingStream xdrIn = new XdrBufferEncodingStream (
        requestLength);
    xdrIn.beginEncoding (socket.getInetAddress (), socket.getPort ());
    request.xdrEncode (xdrIn);
    xdrIn.endEncoding ();
    outputStream.write (xdrIn.getXdrData ());
    outputStream.flush ();
    xdrIn.close ();

    // Read response
    BufferedInputStream inputStream = new BufferedInputStream (socket
        .getInputStream ());
    byte[] buffer = new byte[UreMsgBodyLength.MAXIMUM_MSG_LEN];
    int bytesRead = inputStream.read (buffer);

    if (bytesRead < UreMsgBodyLength.MESSAGE_HEADER_LEN)
      throw new IOException("Socket Read Failed - invalid bytesRead="+bytesRead);


    int encodedLength = bytesRead;
    if ( encodedLength < 0 || ( encodedLength & 3) != 0 )
      encodedLength = UreMsgBodyLength.MAXIMUM_MSG_LEN;

   XdrBufferDecodingStream xdrOut = new XdrBufferDecodingStream (buffer, encodedLength);
    xdrOut.beginDecoding ();
    response.xdrDecode (xdrOut);
    xdrOut.endDecoding ();
    xdrOut.close ();
    return response;
  }
  catch (ConnectException ex)
  {

    ioException = ex;
  }
  catch (IOException ex)
  {

    ioException = ex;

    if (socket != null)
    {
      needResetPool = true;
      try { socket.close (); } catch (Throwable t) {}

      try
      {
        pool.invalidateObject (socket);          // Mark the socket as invalid

      }
      catch (Throwable t)
      {

      }
      socket = null;
    }
  }
  finally
  {    
    if (socket != null)
    {
      try
      {
        pool.returnObject (socket);
      }
      catch (Throwable t)
      {

      }
    }
  }

  if (attempts >= MAXIMUM_RETYR_BEFORE_RESET_POOL && needResetPool)
  {

    pool.clear (pool.getKey ()); // clean all connect for the current server id
  }
  if (attempts >= MAXIMUM_RETRY)
  {

    throw ioException;
  }

  attempts++;

} // while

}

关闭连接时我缺少什么?

服务器没有关闭其套接字以响应读取EOS(read()返回-1)。 此代码也无法很好地处理它。 CLOSE_WAIT表示对等方已关闭连接,并且本地系统正在等待应用程序关闭此端。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM