Timeout socket timeout что это

Socket Timeout — An Important and Sometimes Complicated Issue with Python

Timeout socket timeout что это

During my experience working with Python, I’ve had several cases where a network client was left hanging while trying to request a server. After spending some time researching, the root cause was identified and it was found that the server was waiting for a response but there was silence (like being ghosted on a Tinder match).

Timeout socket timeout что это

Of course, an operating system can raise a Connection timed out error, but it doesn’t always seem to happen on hang connections. If it did, probably wouldn’t even run into this issue on the job.

In order to avoid the annoying problem of waiting for an undetermined amount of time, sockets (which are responsible for network communication) support a timeout option which raises an error based on a time limit. Unfortunately, when developers develop their amazing network libraries, they may omit such non-obvious cases and forget to provide socket timeout settings, despite of the docs recommendation:

Let’s look at a simple example of how to simulate hang socket (at a minimum level in Mac OS):

Before I go into showing issue solution, let’s go deep into Python socket implementation in order to understand why it hangs.

Let’s see how the timeout option helps with a hang socket:

As said above, this option can be omitted in libraries which use sockets. Fortunately, Python gives you a chance to set up socket timeout for all new sockets, which will be created during application work:

If this would be enough, the article would finish here. Unfortunately, socket timeout can be reset with a sock.settimeout(None) that some libraries do rather rashly.

A solution for this is monkey-patching of the socket module, like this:

But in the socket there is another way to reset timeout:

Let’s see what happens under the hood of this method:

Here it changes the timeout, without worrying about its default value. Why it works this way you can read more about in the socket docs, but it’s easy to patch:

No more hang sockets any longer.

Keep in mind that these socket monkey-patches may prevent developers from setting a socket blocking mode if the default timeout is set. Unfortunately some libraries do this thing unconsciously and you ultimately have to choose between canonical and working code.

Источник

ConnectionTimeout versus SocketTimeout

I’m having a problem with a library that I am using. It might be the library or it might be me using it wrong!

Basically, when I do this (Timeout in milliseconds)

No timeout exception is generated and it works ok, however, when I do the following,

I get a Socket Exception.

So, my question is why can I not simulate a Connection Exception? Am I misunderstanding the difference between a socket and a connection time-out? The library is here (not officially released yet).

Timeout socket timeout что это

2 Answers 2

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.

By setting socket timeout to 1 this would require that every millisecond new data is received (assuming that you read the data block wise and the block is large enough)!

If only the incoming stream stalls for more than a millisecond you are running into a timeout.

Источник

Как настроить таймаут подключения к сокету

Код, который я использую для установки сокет-соединения, следующий:

10 секунд, поэтому функция возвращается не по прошествии заданного промежутка времени, а по прошествии промежутка времени + время

Я не программирую на C #, но на C мы решаем ту же проблему, делая сокет неблокирующим, а затем помещая fd в цикл выбора / опроса со значением тайм-аута, равным времени, в течение которого мы готовы ждать подключения. преуспеть.

Я нашел это для Visual C ++, и объяснение там также склоняется к механизму выбора / опроса, который я объяснял ранее.

По моему опыту, вы не можете изменить значения таймаута подключения для каждого сокета. Вы меняете его для всех (настраивая параметры ОС).

может быть уже слишком поздно, но есть отличное решение на основе Task.WaitAny (c # 5 +):

Я решил проблему, используя метод Socket.ConnectAsync вместо метода Socket.Connect. После вызова Socket.ConnectAsync (SocketAsyncEventArgs) запустите таймер (timer_connection), если время истекло, проверьте, подключено ли соединение с сокетом (если (m_clientSocket.Connected)), если нет, появится ошибка тайм-аута.

Плакат на MSDN фактически решил свою проблему с помощью потоковой передачи. У него был основной поток, который вызывал другие потоки, которые запускали код соединения в течение пары секунд, а затем проверяли свойство Connected сокета:

Что вы пытаетесь сделать, и почему он не может подождать 15-30 секунд до истечения времени ожидания?

У меня была такая же проблема при подключении к сокету, и я придумал следующее решение: оно отлично работает для меня. `

Я работал с Unity, и у меня были проблемы с BeginConnect и другими асинхронными методами из сокета.

Я кое-что не понимаю, но предыдущие примеры кода мне не подходят.

Итак, я написал этот фрагмент кода, чтобы он работал. Я тестирую его в специальной сети с Android и ПК, а также локально на моем компьютере. Надеюсь, это поможет.

и есть очень простой сторожевой таймер на C #, чтобы заставить его работать:

Это похоже на ответ FlappySock, но я добавил к нему обратный вызов, потому что мне не понравился макет и то, как возвращалось логическое значение. В комментариях к этому ответу Ника Миллера:

Источник

Как настроить тайм-аут подключения сокета

когда клиент пытается подключиться к отключенному IP-адресу, существует длительный тайм-аут более 15 секунд. Как мы можем уменьшить этот таймаут? Каков способ его настройки?

код, который я использую для настройки подключения сокета, выглядит следующим образом:

10 ответов:

Я не программирую на C#, но в C мы решаем ту же проблему, делая сокет неблокирующим, а затем помещая fd в цикл select/poll со значением тайм-аута, равным количеству времени, которое мы готовы ждать успешного подключения.

нашел этой для Visual C++ и объяснение там также склоняется к механизму выбора / опроса, который я объяснил ранее.

по моему опыту, вы не можете изменить значения времени ожидания подключения в розетку. Изменения это для всех (путем настройки параметров ОС).

Я решил проблему с помощью сокетов.Метод ConnectAsync вместо сокета.метод Connect. После вызова сокета.ConnectAsync (SocketAsyncEventArgs), запустите таймер (timer_connection), если время истекло, проверьте, подключено ли соединение сокета(if (m_clientSocket.Подключен)), если нет, всплывает ошибка тайм-аута.

проверьте это на MSDN. Не похоже, что вы можете сделать это с помощью реализованных свойств в классе сокета.

Плакат на MSDN на самом деле решил свою проблему С помощью резьбы. У него был основной поток, который вызывал другие потоки, которые запускали код соединения в течение нескольких секунд, а затем проверяли свойство Connected сокета:

Что вы пытаетесь сделать, и почему он не может ждать 15-30 секунд, прежде чем тайм-аут?

Я работал с Unity и имел некоторые проблемы с BeginConnect и другими асинхронными методами из сокета.

есть что-то, чем я не понимаю, но примеры кода, пока не работает для меня.

поэтому я написал этот кусок кода, чтобы заставить его работать. Я тестирую его в сети adhoc с android и ПК, а также в локальном на моем компьютере. Надеюсь, это поможет.

и там очень простой сторожевой пес на C#, чтобы заставить его работать:

Это похоже на ответ FlappySock, но я добавил к нему обратный вызов, потому что мне не понравился макет и как возвращалось логическое значение. В комментариях к этому ответу от Ника Миллера:

Источник

IO::Socket::Timeout: socket timeout made easy

Without network operations, running a website for booking accommodation online would be nearly impossible. Network operations can be anything from simple actions like talking to a browser with a user at the other end, to providing an API for our affiliates, or even writing the internal services that help maintain our systems.

Timeout socket timeout что это

Timeout socket timeout что это

Network operations are everywhere, and these are only a few examples of where we use them.

What is a network socket

Network communication typically happens through the use of sockets.

A network socket is one of the core software components of all modern operating systems. It is a software interface for network services provided by the operating system. It provides a uniformed way of opening a connection to this service and sends and receives data.

Network sockets are used everywhere in the IT world, and they allow us to communicate between different hosts or different programs on the same host. Despite having different kinds of network services ( TCP and UDP being prominent examples), network sockets provide a common way to interact with them.

Here is an example of interacting with the Google.com website using IO::Socket::INET, the standard Perl socket module. ( IO means Input/Output, and INET means Internet.)

Interestingly, IO::Socket::INET is mostly used for its Object Oriented capable interface. The following example performs the same operations as the previous one, but in an object oriented way:

Why sockets timeouts are important

At Booking.com, the handling of requests in a timely manner is critical to the user experience, to operations, and ultimately to our business. To achieve speed and low latency, our platform involves different subsystems and resources are constantly requested.

It is essential that these systems reply quickly. It is also vital that we detect when one of them isn’t replying fast enough, that way it can be flagged and a mitigating strategy can be found (such as using an alternative subsystem).

We use Redis in a lot of places: as a cache layer, queue system, and for storage. Redis offers very low latency, and we make use of this feature. However, with sockets, we don’t always know immediately when a connection has been lost. Knowing a Redis server is unreachable 30 seconds after the fact — is 30 seconds too late. Our goal is to know this in under a second. For other cases it might be possible (or even mandatory) to allow a longer timeout. It really depends on the subsystems involved as well as the usage.

Most of the time these subsystems are queried using a network socket. So being able to detect that a subsystem is not reachable implies that the sockets provide a way to specify timeouts.

This is why having a fast and reliable platform relies on having sockets that support timeouts. Using a socket involves three main steps: connecting to the external server, reading and writing data from and to it, and, at some point, closing the connection. A socket timeout implementation should allow for setting the timeout at connections, and both reading and writing steps at the very least.

Connection timeout

IO::Socket provides a timeout method, and IO::Socket::INET provides a Timeout option. The Timeout option can be used to set a timeout on the connection to the server. For example, this is how we connect to a local HTTP server on port 80 with a connection timeout of 3 seconds:

So far so good, but how do we deal with read or write timeouts? What if the server accepts the connection, but then at some point stops communicating? The client socket needs to realize this quickly. We need timeouts for this.

Read/Write timeouts via setsockopt

Read/Write timeouts via select

Another more portable (albeit slower) way to simulate a timeout on a socket is to check if the socket is readable/writable with a timeout in a non-blocking way. select(2) can do this, and the Perl select() function can provide access to it.

Here is a simplified version of a function that returns true if we can read the socket with the given timeout:

Using an external library

Yet another way is to use external modules or system calls, like epoll (via IO::Poll), libevent, or libev. To simplify things, it’s common to use higher-level event-based modules like AnyEvent and POE. They make it easy to specify a timeout to any IO (Input/Output) operations.

While completely valid, it applies only to programs that use these event-based modules. It is useless to standard imperative programs. We need a method for providing timeout features to the standard socket API without changing the operation needed to require an event loop.

Provide a nice API

Let’s step back for a moment. We have two ways to setup a timeout on a socket:

We need to abstract these two ways of setting timeouts behind a simple and easy-to-use API. Let’s consider this example:

(Please note that we don’t use object-oriented notations on the socket.)

when using setsockopt

when using select

Overwriting a core function is not a good practice for various reasons. Luckily, Perl provides a clean way to implement custom behavior in the IO layer.

PerlIO layers

Perl Input/Output mechanism is based on a system of layers. It is documented in the perliol(1) man page.

These layers can be stacked and removed in order to provide more features (when layers are added) or more performance (when layers are removed).

The huge benefit is that no matter which layers are setup on a file handle or socket, the API doesn’t change and the read/write operations are the same. Calls to them will go through the specified layers attached to the handle until they potentially reach the system calls.

Here is an example:

The :via layer is a special layer that allows anyone to implement a PerlIO layer in pure Perl. Contrary to implementing a PerlIO layer in C, using the :via layer is rather easy: it is just a Perl class, with some specific methods. The name of the class is given when setting the layer:

Many :via layers already exist. They all start with PerlIO::via:: and are available on CPAN. For instance, PerlIO::via::json will automatically and transparently decode and encode the content of a file or a socket from and to JSON.

Back to the problem. We could implement a :via layer that makes sure that read and write operations on the underlying handle are performed within the given timeout.

Implementing a timeout PerlIO layer

Let’s take the READ method as an illustration. This is a very simplified version. The real version handles EINTR and other corner cases.

The idea is to check if we can read on the filesystem using select in the given timeout. If not, return 0. If yes, call the normal sysread operation. It’s simple and it works great.

We’ve just implemented a new PerlIO layer using the :via mechanism! A PerlIO layer works on any handle, including file and socket. Let’s try it on a file-handle:

I’m sure you can see that there is an issue in the code above. At no point do we set the read timeout value. The :via pseudo-layer doesn’t allow us to easily pass a parameter to the layer creation. Though we can technically, we would not be able to change the parameter afterwards. If we want to be able to set, change, or remove the timeout on the handle at any time, we need to somehow attach this information to the handle, and we need to be able to change it.

Add a properties to a Handle using InsideOut OO

A handle is not an object. We can’t just add a new timeout attribute to a handle and then set or get it.

Luckily, the moment a handle is opened it receives a unique ID: its file descriptor. A file descriptor is not always unique because they are recycled and reused. Yet, if we know when a handle is opened and closed we can be sure that between these actions a file descriptor is given that uniquely identifies it.

We can create a hash table as a class attribute of our new layer. Here the keys are file descriptors and the values are a set of properties on the associated handle — essentially a basic implementation of Inside-Out OO — with the object not being its data structure only an ID. Using this hash table, we can associate a set of properties to a file descriptor and set the timeout value when the PerlIO layer is added. Like this:

By doing this when we remove the layer too, we can also implement a way to associate timeout values to the file-handle.

Wrapping up all the bits of code and features, the full package that implements this timeout layer, PerlIO::via::Timeout, is available on Github and CPAN.

Implement the API

We now have all the ingredients we need to implement the desired behavior. enable_timeouts_on will receive the socket and modify its class (which should be IO::Socket::INET or inherited from it) to implement these methods:

In order to modify the IO::Socket::INET class in a clean way, let’s create a role and apply it to the class. In fact, let’s create two roles: one that implements the various methods using setsockopt and another role that uses select (with PerlIO::via::Timeout ).

A Role (sometimes known as Trait) provides additional behavior to a class in the form of composition. Roles provide introspection, mutual exclusion capabilities, and horizontal composition instead of the more widely used inheritance model. A class simply consumes a Role, receiving any and all behavior the Role provides, whether these are attributes, methods, method modifiers, or even constraints on the consuming class.

wrap it up

Conclusion

IO::Socket::Timeout provides a lightweight, generic, and portable way of applying timeouts on sockets, and it plays an important role in the stability of the interaction between our subsystems at Booking.com. This wouldn’t be possible without Perl’s extreme flexibility.

Please be aware that there is a performance penalty associated with implementing IO layers in pure Perl. If you are worried about this, we recommend benchmarking when making the decision on whether to use it.

IO::Socket::Timeout is available on GitHub and CPAN.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *