1. 소개

이 사용방법(예제)에서는 Java 소켓 프로그래밍 의 시간 초과 예외에 중점을 둘 것입니다 . 우리의 목표는 이러한 예외가 발생하는 이유와 처리 방법을 이해하는 것입니다.

2. 자바 소켓과 타임아웃

소켓은 두 컴퓨터 응용 프로그램 사이의 논리적 링크의 한 Endpoints입니다 . 즉, 응용 프로그램이 네트워크를 통해 데이터를 보내고 받는 데 사용하는 논리적 인터페이스입니다.

일반적으로 소켓은 IP 주소와 포트 번호의 조합 입니다 . 각 소켓에는 서비스를 식별하는 데 사용되는 특정 포트 번호가 할당됩니다.

연결 기반 서비스는 TCP 기반 스트림 소켓을 사용합니다. 이러한 이유로 Java는 클라이언트 측 프로그래밍을 위한 java.net.Socket 클래스를 제공합니다 . 반대로 서버 측 TCP/IP 프로그래밍은 java.net.ServerSocket 클래스를 사용합니다 .

또 다른 유형의 소켓은 연결 없는 서비스에 사용되는 UDP 기반 데이터그램 소켓입니다. Java는 UDP 작업을 위해 java.net.DatagramSocket을  제공합니다 . 그러나 이 사용방법(예제)에서는 TCP/IP 소켓에 중점을 둘 것입니다.

3. 연결 시간 초과

3.1. "연결 시간 초과"란 무엇입니까?

클라이언트 측에서 서버에 대한 연결을 설정하기 위해 소켓 객체를 인스턴스화하는 소켓 생성자가 호출됩니다 . 생성자 는 원격 호스트 주소와 포트 번호를 입력 인수로 사용합니다 . 그런 다음 주어진 매개 변수를 기반으로 원격 호스트에 대한 연결 설정을 시도합니다.

이 작업은 성공적으로 연결될 때까지 다른 모든 프로세스를 차단합니다 . 그러나 일정 시간이 지난 후에도 연결에 실패하면 프로그램에서 "Connection timed out" 메시지와 함께 ConnectionException이 발생합니다.

java.net.ConnectException: Connection timed out: connect

서버 측에서 ServerSocket 클래스는 들어오는 연결 요청을 지속적으로 수신합니다. ServerSocket은 연결 요청을 받으면 accept() 메서드를 호출하여 소켓 개체를 인스턴스화합니다 . 마찬가지로 이 메서드도 원격 클라이언트와 성공적으로 연결될 때까지 차단됩니다.

TCP 핸드셰이크가 완료되지 않으면 연결이 실패한 상태로 유지됩니다. 결과적으로 프로그램은 새 연결을 설정하는 동안 오류가 발생했음을 나타내는 IOException 을 발생시킵니다 .

3.2. 왜 발생합니까?

연결 시간 초과 오류에는 여러 가지 이유가 있을 수 있습니다.

  • 원격 호스트에서 지정된 포트를 수신하는 서비스가 없습니다.
  • 원격 호스트가 연결을 수락하지 않습니다.
  • 원격 호스트를 사용할 수 없습니다.
  • 느린 인터넷 연결
  • 원격 호스트에 대한 전달 경로 없음

3.3. 그것을 처리하는 방법?

차단 시간은 제한되지 않으며 프로그래머는 클라이언트 및 서버 작업 모두에 대해 시간 제한 옵션을 미리 설정할 수 있습니다 . 클라이언트 측에서는 먼저 빈 소켓을 만듭니다. 그런 다음 connect(SocketAddress endpoint, int timeout) 메서드를 사용 하고 timeout 매개변수를 설정합니다.

Socket socket = new Socket(); 
SocketAddress socketAddress = new InetSocketAddress(host, port); 
socket.connect(socketAddress, 30000);

시간 초과 단위는 밀리초 이며 0보다 커야 합니다. 그러나 메서드 호출이 반환되기 전에 시간 초과가 만료되면 SocketTimeoutException 이 발생합니다 .

Exception in thread "main" java.net.SocketTimeoutException: Connect timed out

서버측에서는 setSoTimeout(int timeout) 메서드를 사용하여 시간 초과 값을 설정합니다. 제한 시간 값 은 ServerSocket.accept() 메서드가 차단하는 기간을 정의합니다 .

ServerSocket serverSocket = new new ServerSocket(port);
serverSocket.setSoTimeout(40000);

마찬가지로 시간 제한 단위는 밀리초여야 하며 0보다 커야 합니다. 메서드가 반환되기 전에 시간 제한이 경과하면 SocketTimeoutException 이 발생 합니다 .

Security상의 이유로 방화벽이 특정 포트를 차단하는 경우가 있습니다 . 따라서 클라이언트가 서버에 연결을 시도할 때 "연결 시간 초과" 오류가 발생할 수 있습니다. 따라서 포트를 서비스에 바인딩하기 전에 방화벽 설정을 확인하여 포트를 차단하고 있는지 확인해야 합니다 .

4. 읽기 시간 초과

4.1. "읽기 시간 초과"란 무엇입니까?

소켓에서 데이터 바이트 읽기를 완료할 때까지 InputStream 에서 read () 메서드 호출이 차단됩니다. 작업은 소켓에서 적어도 하나의 데이터 바이트를 읽을 때까지 기다립니다. 그러나 메서드가 지정되지 않은 시간 이후에 아무 것도 반환하지 않으면 “Read timed out” 오류 메시지와 함께 InterrupedIOException 이 발생합니다 .

java.net.SocketTimeoutException: Read timed out

4.2. 왜 발생합니까?

클라이언트 측에서 "읽기 시간 초과" 오류는 서버가 응답하고 정보를 보내는 데 시간이 더 오래 걸리면 발생합니다 . 인터넷 연결이 느리거나 호스트가 오프라인 상태일 수 있습니다.

서버 측에서는 서버가 미리 설정된 시간 초과에 비해 데이터를 읽는 데 시간이 오래 걸리는 경우에 발생합니다 .

4.3. 그것을 처리하는 방법?

TCP 클라이언트와 서버 모두에 대해 socketInputStream.read() 메서드가 setSoTimeout(int timeout) 메서드를 사용하여 차단하는 시간을 지정할 수 있습니다 .

Socket socket = new Socket(host, port);
socket.setSoTimeout(30000);

그러나 메서드가 반환되기 전에 시간 초과가 경과하면 프로그램에서 SocketTimeoutException 이 발생합니다 .

5. 결론

이 기사에서는 Java 소켓 프로그래밍의 시간 초과 예외에 대해 논의하고 이를 처리하는 방법을 배웠습니다.

항상 그렇듯이 코드는 GitHub에서 사용할 수 있습니다 .

res – REST with Spring (eBook) (everywhere)