connection timeout / socket timeout / read timeout

Connection Timeout

  • 웹 브라우저가 네이버 서버에 접속하기 위해 서버와 연결된 상태가 되어야 한다.

  • 연결구성하기 위해서 보통 TCP Connection과 동일하게 3-way Handshake 방식으로 수행하게 된다.

  • 3-way Handshake정상적으로 수행하게 되면 웹 브라우저와 네이버 서버는 연결된 상태가 된다.

  • 이 때까지 소요된 시간Connection소요된 시간이라고 할 수 있다.

  • Connection TimeoutConnection구성하는데 소요되는 시간의 임계치를 의미한다.


Socket Timeout

  • 보통 서버는 클라이언트와 Established 후 데이터를 클라이언트에게 전송한다.

  • 이 때 하나의 패킷이 아니라 여러 개의 패킷으로 나눠서 전송한다.

  • 각 패킷이 전송될 때 시간 Gap이 생길 수 있는데 이 시간의 임계치Socket Timeout이라고 한다.

  • Socket Timeout개별 패킷기다리는 Timeout이다.

  • 주의할 점은 Socket Timeout이 전체 응답을 수신하는 Timeout이라고 생각하는 것이다.

  • 다시말해 전체 응답이 아닌 개별 응답에 대한 시간 제한이다.

  • 따라서 Timeout 시간 제한이 1초이고 응답 패킷이 3개일 경우 (각 패킷 도착 시간이 0.9초 )
    총 응답 시간이 2.7초가 걸리지만 Timeout이 발생하지 않는다.

  • 결론적으로 URL을 호출할 때에는 Connection TimeoutSocket Timeout 설정이 모두 필요하다.

Q. 만약 두 가지 Timeout을 설정하지 않으면 어떤 일이 벌어질까?

  • URL 접속시 무한 대기가 발생할 수 있다.

Read Timeout

/**
 * Sets the read timeout to a specified timeout, in
 * milliseconds. A non-zero value specifies the timeout when
 * reading from Input stream when a connection is established to a
 * resource. If the timeout expires before there is data available
 * for read, a java.net.SocketTimeoutException is raised. A
 * timeout of zero is interpreted as an infinite timeout.
 *
 *<p> Some non-standard implementation of this method ignores the
 * specified timeout. To see the read timeout set, please call
 * getReadTimeout().
 *
 * @param timeout an <code>int</code> that specifies the timeout
 * value to be used in milliseconds
 * @throws IllegalArgumentException if the timeout parameter is negative
 *
 * @see #getReadTimeout()
 * @see InputStream#read()
 * @since 1.5
 */
public void setReadTimeout(int timeout) {
   if (timeout < 0) {
      throw new IllegalArgumentException("timeout can not be negative");
   }
   readTimeout = timeout;
}
  • Read TimeoutSocket Timeout과 유사하다고 볼 수 있다.

Connection vs Socket

  • A는 최대 10분까지 맛집을 가기위해 기다릴 생각이 있다.

  • 10분을 넘게 기다렸지만 A(=클라이언트)는 맛집(=서버)을 들어가지 못해 떠났다.

  • 이처럼 서버에 클라이언트가 접근을 시래했을 시 적용되는 것이 Connection Timeout이다.

  • 즉 접근을 시도하는 시간 제한(=10분)이 Connection Timeout이 되는 것이다.

  • 만약 A가 10분 안에 맛집에 들어갔다고 가정해보자.

  • 그리고 A는 음식을 기다리는데 최대 5분을 소요할 생각이 있다.

  • 5분이 지난 A는 그냥 가게를 나왔다.

  • 즉 클라이어트가 서버에 접속은 성공했으나 클라이언트가 원하는 요청에 대해
    서버가 너무 오랫동안 응답을 못해 클라이언트가 연결을 해제하는 것이 Read Timeout이다.

  • 이런 경우 클라이언트는 현 상황을 오류로 인지하고(=음식이 안나옴)
    서버는 계속 요청(=요리중)을 수행하고 있기 때문에 요청 성공으로 인지를 한다.

  • 이로인해 클라이언트와 서버간 싱크가 맞지 않아 문제가 발생할 확률이 높다.


Stack OverFlow

Q. ConnectionTimeout versus SocketTimeout

A connection timeout occurs only upon starting the TCP connection. 
This usually happens if the remote machine does not answer. 
This means that the server has been shut down, you used the wrong IP/DNS name, wrong port or the network connection to the server is down.

A socket timeout is dedicated to monitor the continuous incoming data flow. 
If the data flow is interrupted for the specified timeout the connection is regarded as stalled/broken. 
Of course this only works with connections where data is received all the time. 

번역

A connection timeout is the maximum amount of time that the program is willing to wait to setup a connection to another process. 
You aren't getting or posting any application data at this point, just establishing the connection, itself.

A socket timeout is the timeout when waiting for individual packets. 
It's a common misconception that a socket timeout is the timeout to receive the full response. 
So if you have a socket timeout of 1 second, and a response comprised of 3 IP packets, where each response packet takes 0.9 seconds to arrive, for a total response time of 2.7 seconds, then there will be no timeout.

번역


Q. What is the difference between connection and read timeout for sockets?

The connection timeout is the timeout in making the initial connection
i.e. completing the TCP connection handshake. 
The read timeout is the timeout on waiting to read data1. 
Specifically, if the server fails to send a byte <timeout> seconds after the last byte, a read timeout error will be raised.

번역


참고