2015-06-30 2 views
1

Я использую Python 2.7 и работаю с некоторым устаревшим кодом. Он устанавливает сокет в режиме без блокировки с:Каково значение тайм-аута для неблокирующего сокета Python при чтении?

self._socket.setblocking(0) 
self._socket.settimeout(0) 

Мой вопрос, при выполнении чтения, что определяет тайм-аут на сокет? Будет ли это по умолчанию использоваться стеком TCP в ОС? Если да, то в Linux, как это изменится? Кроме того, будет ли время ожидания записи совпадать с таймаутом чтения?

ответ

2

Согласно documentation (курсив мой):

В неблокирующая режим, если recv() вызов не находит каких-либо данных, или если в send() вызов не может сразу отчуждать данные, error исключение поднят.

Так что кажется, что «таймаут» является мгновенной проверкой. Если данных нет или запись не может быть выполнена точно при вызове функции, вы получите исключение.

2

Ниже с помощью socket.settimeout

SetTimeout (...) методом socket._socketobject экземпляра SetTimeout (тайм-аут)

Установите тайм-аут на операции сокета. «тайм-аут» может быть плавающим, в секундах или None. Установка таймаута None отключает функцию таймаута и эквивалентна setblocking(1). Установка времени ожидания равна setblocking(0).

Так что я не знаю, почему так setblocking(0) и settimeout(0) как это сделано выше. Это означает, что read сразу же вернется с EAGAIN или EWOULDBLOCK, если данных нет. Когда другой конец закроет соединение, read вернется со значением 0.

Чтение тайм-аута будет иметь смысл только в состоянии «блокировки», когда по истечении времени, равного таймауту, и нет данных для чтения, чтение должно возвращать или EWOULDBLOCK.

В общем, это не повлияет на write таймаут. Когда вы устанавливаете сокет на неблокирующийся, и если «буферы записи» заполнены (что редко случается, если нет достаточно «медленного» приемника), и если write, вероятно, будет блокироваться, он должен немедленно вернуться сили EWOULDBLOCK, а затем бремя ответственности за приложение, чтобы убедиться, что write выдается снова.

+0

Вы имеете в виду 'EAGAIN' или' EWOULDBLOCK' вместо 'EINTR' (последний может быть поднят, если сигнал получен во время системного вызова (блокировки?) В текущей версии Python. В Python 3.5+ вы не должны видеть 'EINTR': [PEP 0475 - сбои системных вызовов повторно с EINTR] (https://www.python.org/dev/peps/pep-0475/) – jfs

+0

Прошу прощения - да, это' EAGAIN' или 'EWOULDBLOCK ' – gabhijit

+0

Отредактировано. исправить ошибки – gabhijit