2009-08-13 5 views
2

C++로 작성된 서버의 소켓을 통해 요청하는 Java 코드가 있습니다. 통신은 단순히 자바 코드가 요청에 대한 라인을 작성한 다음 서버가 응답으로 라인을 작성하지만 때로는 서버가 응답하지 않는 것처럼 보이기 때문에 ExecutorService 기반 타임 아웃을 구현하여 삭제하려고 시도합니다. 연결을 다시 시작하십시오.비정상적인 소켓 서버에 대한 클라이언트 연결을 끊고 다시 시작하는 방법

가 연결 작업을하려면 나는 유지 :이 타임 아웃 코드 요청 아니었다면

server = new Socket(hostname, port); 
out = new PrintWriter(new OutputStreamWriter(server.getOutputStream())); 
in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 

은/단계가 나타납니다

Socket server; 
PrintWriter out; 
BufferedReader in; 

때문에 연결을 설정하는 문제이다 간단히 :

String request="some request"; 
out.println(request); 
out.flush(); 
String response = in.readLine(); 

연결을 닫으려고 할 때 :

in.close(); 
out.close(); 
socket.close(); 

그러나이 중 하나가 차단되어 반환되지 않는 것으로 보입니다. 아무도 내게 왜 이들 중 하나가 차단하고 연결을 포기하고 리소스 누출 문제로 끝내지 않을 적절한 방법이 될 것이라고 단서를 줄 수 있습니까?

답변

0

소켓을 감싸는 버퍼가있는 리더/라이터를 닫으면 소켓이 닫힙니다.
이미 닫힌 소켓 닫기가 올바르지 않지만 문제가되지 않습니다.

자바 소켓에 따라 : 일단 소켓이 닫히면 나중에 사용할 수 없으므로 다시 연결하거나 리바운드 할 수 없습니다. 새 소켓을 만들어야합니다.

그래서이 소켓을 닫은 후에 새 소켓 객체를 만들어야합니다.

당신의 메모리 관리가가는 한, 쓰레기 처리기는 당신을 위해 당신의 오래된 것을 죽여야하므로, 누출에 대해 걱정하지 마십시오.

0

PrintWriter.close() 메서드가 println (String) 메서드와 동일한 잠금에서 동기화되기 때문에 out.close()를 호출 할 수 없습니다. println의 원의 호출이 불량한 접속에 기입하려고하면 (자) 블록되면, close()를 호출 할 수 없습니다.

Socket.setSoTimeout() 메소드를 사용해 보셨습니까?

+0

필자는 setSoTimeout()을 호출하지 않았지만 쓰기 호출 (out.close()도 차단 된 것처럼 보입니다)에서 차단되는 경우 읽기 호출에만 영향을 미친 것처럼 들립니다. 그게 날 도와주지 않을거야 - 맞지? –

0

나는 소켓을 닫고 (그에 따라 읽기/쓰기 쓰레드에서 예외를 처리해야 함) 생각하면된다. 또한, 위에서 말했듯이 소켓을 처음부터 다시 만드십시오.

관련 문제