클라이언트 재시작 또는 종료를 수행하는 동안 모든 소켓 연결은 서버 측의 CLOSE_WAIT에 정지합니다. XdrAble은 직렬화 된 데이터를 XDR 스트림으로 보내는 데 사용됩니다. 풀은 표준 KeyedSocketPool의 객체입니다. MAXIMUM_RETRY, MAXIMUM_RETYR_BEFORE_RESET_POOL은 풀 연결을 재설정하기 위해 정의 된 상수입니다. 연결을 닫는 동안 내가 누락되었습니다.Java 서버 소켓 클라이언트 종료 또는 클라이언트 재시작 중 TCP 연결이 CLOSE_WAIT 상태로 고정됨
공개 RESP 호출 (REQ 요청 RESP 응답의 INT requestLength, INT 시간 초과)는 예외 {
소켓 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
}
안녕하세요. EJP가 EOS 용 조건 인 경우 위의 코드 & 장소에서 업데이트되었지만 나에게 적합하지 않습니다. 더 자세히 설명해 주실 수 있습니까? ....... if (bytesRead
rahulpoorey
@rahulpoorey 주석의 코드는 거의 판독 할 수 없지만 'if (bytesRead == -1)'여야합니다. 캐스트를 제거하십시오. 그리고 길이 테스트 전에 그 시험을 치십시오. 사실, * 길이 테스트를 제거합니다 : 그것을 루프로 변환하거나'DataInputStream.readFully()'를 사용하십시오. TCP는 언제나 당신에게 바이트 수를 제공 할 수 있습니다 : 당신은 잘못 놓인 기대가 실망 스러울 때'IOExceptions'를 던지지 않습니다. – EJP