Reputation: 21
While performing Client restart or shutdown,all socket connections are hang in CLOSE_WAIT on server side. XdrAble used to send serialized data into XDR streams. pool is object of standard KeyedSocketPool. MAXIMUM_RETRY,MAXIMUM_RETYR_BEFORE_RESET_POOL are constants defined to reset the pool connections. What I am missing while closing the connections?
public RESP call (REQ request,
RESP response, int requestLength, int timeOut) throws Exception
{
Socket socket = 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
}
Upvotes: 2
Views: 4310
Reputation: 310869
What am I missing while closing the connections?
The server isn't closing its sockets in response to reading EOS (read() returns -1). This code doesn't handle it well either. CLOSE_WAIT means that the peer has closed the connection and the local system is waiting for the application to close this end.
Upvotes: 1