4Way HandShake를 정상적으로 수행했을 때를 정상 종료라고 한다. 자바에서 네트워크 프로그래밍 (소켓 프로그래밍)을 할 때 정상 종료 시에는 어떻게 처리를 해주어야 하는 지 알아보자.

서버가 연결을 종료하기 위해 socket을 close한다. 그러면 클라이언트에 FIN 패킷이 전달된다. 클라이언트는 FIN 패킷을 받고 클라이언트의 socket을 종료한다. 클라이언트의 socket을 종료하면, 서버에 FIN+ACK 패킷이 전달된다. 서버에서는 ACK를 클라이언트에 전송함으로서 TCP 연결이 종료된다.
서버로 부터 받은 데이터를 가져오는 Stream에서는 클래스마다 FIN 패킷 수신을 알리는 방법이 다르다.
FIN 패킷을 수신했으면, 자원을 정리하면 된다.
FIN을 받은 쪽에서 FIN을 받은 뒤에는 FIN+ACK를 보내야 하는데 데이터를 송신하는 PUSH 패킷처럼 다른 패킷을 전송하면 상대는 장애가 발생했다고 판단하여 RST 패킷을 전달한다. 이를 비정상 종료라고 한다.

java.net.SocketException을 던진다.java.net.SocketException을 던진다.SocketException을 catch하면 자원을 모두 정리해주면 된다.
정상 종료, 비정상 종료는 결국 발생하면 자원을 정리하면 된다. SocketException, EOPException은 모두 IOException의 자식이다. 따라서 IOException이 발생하면 자원을 정리하면 된다.
네트워크 프로그래밍을 할 때 (정확히는 TCP 기반인 경우) 주의해야 하는 점은 꼭 timeout 설정을 해주어야 한다. 서버와 연결이 되지 않을 때 발생하는 ConnectTimeout, 서버로 부터 응답이 오지 않을 때 발생하는 ReadTimeout을 꼭 설정해주어야 한다. 그 이유는 timeout을 설정해주지 않았다가 스레드가 모두 행에 걸려서 서비스가 먹통이 될 수 있다. 자세한 내용은 아래 링크를 참고하자.