Http socket timeout java

Тайм-аут соединения и тайм-аут чтения для сокетов Java

В этом руководстве мы сосредоточимся на исключениях тайм-аута в программировании сокетов Java . Наша цель — понять, почему возникают эти исключения и как с ними работать.

2. Сокеты Java и тайм-ауты​

Сокет — это конечная точка логической связи между двумя компьютерными приложениями . Другими словами, это логический интерфейс, который приложения используют для отправки и получения данных по сети.

В общем случае сокет представляет собой комбинацию IP-адреса и номера порта . Каждому сокету назначается определенный номер порта, который используется для идентификации службы.

Службы на основе соединений используют сокеты потока на основе TCP . По этой причине Java предоставляет класс java.net.Socket для программирования на стороне клиента . С другой стороны, в программировании TCP/IP на стороне сервера используется класс java.net.ServerSocket .

Другим типом сокета является сокет дейтаграмм на основе UDP, который используется для служб без установления соединения. Java предоставляет java.net.DatagramSocket для операций UDP . Однако в этом руководстве мы сосредоточимся на сокетах TCP/IP.

3. Время ожидания соединения истекло​

3.1. Что такое «время ожидания соединения истекло»?​

Для установления соединения с сервером со стороны клиента вызывается конструктор сокета , который создает экземпляр объекта сокета. Конструктор принимает адрес удаленного хоста и номер порта в качестве входных параметров . После этого он пытается установить соединение с удаленным хостом на основе заданных параметров.

Читайте также:  Http wt bristolcapital ru view doc html mode

Операция блокирует все остальные процессы до тех пор, пока не будет установлено успешное соединение . Однако, если соединение не установлено через определенное время, программа выдает исключение 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 .

Иногда брандмауэры блокируют определенные порты из соображений безопасности . В результате может возникнуть ошибка «время ожидания соединения истекло», когда клиент пытается установить соединение с сервером. Поэтому мы должны проверить настройки брандмауэра, чтобы увидеть, не блокирует ли он порт, прежде чем привязывать его к службе.

4. Тайм-аут чтения​

4.1. Что такое «Время чтения истекло»?​

Вызов метода read() в InputStream блокируется до тех пор, пока он не закончит чтение байтов данных из сокета. Операция ожидает, пока не прочитает хотя бы один байт данных из сокета. Однако, если метод ничего не возвращает по истечении неопределенного времени, он выдает 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 и узнали, как с ними обращаться.

Источник

Timeouts and how to handline in Java

In this article we will try to cover why it’s important to define timeouts for out bound rest calls. Before configuring any timeout let’s understand below some common exceptions for http outbound calls,

Connection timeout

maximum time to wait for the other side to answer «yes, I’m here, let’s talk» when creating a new connection, (ConnectTimeout eventually calls socket.connect(address, timeout), If the connection is not established within the ConnectTimeout specified by you or the library you are using then, you get an error ‘connect timedout

Socket timeout

Is the timeout for waiting for data or, put differently, a maximum period inactivity between two consecutive data packets

Read timeout

Read timeout can happen when there is successful connection established between client and the server and there is an inactivity between data packets while waiting for the server response.

Write timeout

Similar to Read timeout, write timeout can happen when there is successful connection established between client and server, and there is inactivity between data packets while sending the request to the server. The important topic to remember here is that based on the choice of library we use for outbound calls it’s very important that we configure the properties to handle the above mentioned one’s and handle the exception gracefully.

Apache Camel

If we are using Apache Camel ‘http’ component to make the outbound calls then we can configure these properties in following ways, please note that if we don’t define this properties the default values is -1! means connection will never timeout and can have advert effect on the application performance overall. camel.property

 http.urlProxy = http4://ThirdPartyServers?throwExceptionOnFailure=false&httpClient.socketTimeout=$&httpClient.connectTimeout=$ 
 @Override public void configure() throws Exception  configureTimeout(); > private void configureTimeout()  HttpComponent httpComponent = getContext().getComponent("http4", HttpComponent.class); httpComponent.setConnectionTimeToLive(VALUE_IN_MILI);// for closing the idle connection - in milliseconds httpComponent.setSocketTimeout(VALUE_IN_MILI); //socket timeout - in milliseconds httpComponent.setConnectTimeout(VALUE_IN_MILI); // connection timeout - in milliseconds*/ > 

Rest Template

final RequestConfig requestConfig = RequestConfig.custom() .setConnectionRequestTimeout(VALUE_IN_MILI) .setConnectTimeout(VALUE_IN_MILI) .setSocketTimeout(VALUE_IN_MILIs) .build(); final HttpClient httpClient = HttpClients.custom() .setConnectionTimeToLive(VALUE_IN_MILI, SECONDS) .setRetryHandler((IOException exception, int executionCount, HttpContext context) ->  return executionCount  3; >) .setServiceUnavailableRetryStrategy(new DefaultServiceUnavailableRetryStrategy(3, 1)) .setDefaultRequestConfig(requestConfig) .build(); final RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpClient)); 

WebClient

 public WebClient getWebClient()  HttpClient httpClient = HttpClient.create() .tcpConfiguration(client -> client.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, VALUE_IN_MILI) .doOnConnected(conn -> conn .addHandlerLast(new ReadTimeoutHandler(rest.timeout.millis)) .addHandlerLast(new WriteTimeoutHandler(rest.timeout.millis)))); ClientHttpConnector connector = new ReactorClientHttpConnector(httpClient.wiretap(true)); return WebClient.builder() .baseUrl("http://localhost:3000") .clientConnector(connector) .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .build(); > 

Summary

All in all it’s very important to configure these values i.e. connection timeout, read timeout, socket timeout etc so as to terminate the connections after waiting for a specific amount of time rather keeping the connection open indefinitely which can bring issues to overall application performance and stability.

Источник

Java socket timeout: How to set the timeout on a Java socket

Java socket FAQ: How do I set the timeout value on a Java socket? That is, when I’m trying to read data from a Java socket, and I’m not getting any response from the server, how do I make sure my code doesn’t get stuck at this point? (It needs to time out after several seconds.)

Java socket timeout

Answer: Just set the SO_TIMEOUT on your Java Socket, as shown in the following sample code:

String serverName = "localhost"; int port = 8080; // set the socket SO timeout to 10 seconds Socket socket = openSocket(serverName, port); socket.setSoTimeout(10*1000);

Here’s a quote from the Socket class Javadoc, specifically the Javadoc for this setSoTimeout method:

Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds. With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time.

If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. The option must be enabled prior to entering the blocking operation to have effect.

The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout.

Setting the Java socket timeout in milliseconds

As shown in the example Java code above, whenever I deal with calls like this socket timeout setting that involve milliseconds, I write my code this way:

Some programmers give me grief about this, but I think it shows my intent, and it’s also easier for humans to read 10*1000 than it is something like 10000 or 100000 .

Источник

Оцените статью