Мне нужно установить тайм-аут на метод recv сокета python. Как это сделать?
Как установить тайм-аут на метод recv сокета python?
Ответ 1
Типичный подход заключается в использовании select() до тех пор, пока данные не будут доступны или пока не произойдет таймаут. Вызывайте recv()
только когда данные действительно доступны. Чтобы быть в безопасности, мы также устанавливаем сокет в неблокирующий режим, чтобы гарантировать, что recv()
никогда не будет блокироваться бесконечно. select()
также может использоваться для ожидания более чем одного сокета за раз.
import select
mysocket.setblocking(0)
ready = select.select([mysocket], [], [], timeout_in_seconds)
if ready[0]:
data = mysocket.recv(4096)
Если у вас много дескрипторов открытых файлов, poll() является более эффективной альтернативой select()
.
Другой вариант - установить тайм-аут для всех операций в сокете с помощью socket.settimeout()
, но я вижу, что вы явно отклонили это решение в другом ответе.
Ответ 2
there socket.settimeout()
Ответ 3
Как уже упоминалось, select.select()
и socket.settimeout()
будут работать.
Обратите внимание, что вам может потребоваться дважды позвонить в settimeout
, например,
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("",0))
sock.listen(1)
# accept can throw socket.timeout
sock.settimeout(5.0)
conn, addr = sock.accept()
# recv can throw socket.timeout
conn.settimeout(5.0)
conn.recv(1024)
Ответ 4
Вы можете установить время ожидания перед получением ответа и после получения ответа установить его на Нет:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5.0)
data = sock.recv(1024)
sock.settimeout(None)
Ответ 5
Тайм-аут, который вы ищете, - это тайм-аут сокета соединения, а не основной сокет, если вы реализуете серверную сторону. Другими словами, есть еще один тайм-аут для объекта сокета подключения, который является результатом метода socket.accept()
. Следовательно:
sock.listen(1)
connection, client_address = sock.accept()
connection.settimeout(5) # This is the one that affects recv() method.
connection.gettimeout() # This should result 5
sock.gettimeout() # This outputs None when not set previously, if I remember correctly.
Если вы реализуете клиентскую сторону, это будет просто.
sock.connect(server_address)
sock.settimeout(3)
Ответ 6
Как упоминалось в предыдущих ответах, вы можете использовать что-то вроде: .settimeout()
Например:
import socket
s = socket.socket()
s.settimeout(1) # Sets the socket to timeout after 1 second of no activity
host, port = "somehost", 4444
s.connect((host, port))
s.send("Hello World!\r\n")
try:
rec = s.recv(100) # try to receive 100 bytes
except socket.timeout: # fail after 1 second of no activity
print("Didn't receive data! [Timeout]")
finally:
s.close()
Надеюсь, это поможет!!
Ответ 7
Вы можете использовать socket.settimeout()
который принимает целочисленный аргумент, представляющий количество секунд. Например, socket.settimeout(1)
установит время ожидания на 1 секунду
Ответ 8
попробуйте это, он использует базовый C.
timeval = struct.pack('ll', 2, 100)
s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, timeval)
Ответ 9
#! /usr/bin/python3.6
# -*- coding: utf-8 -*-
import socket
import time
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.settimeout(5)
PORT = 10801
s.bind(('', PORT))
print('Listening for broadcast at ', s.getsockname())
BUFFER_SIZE = 4096
while True:
try:
data, address = s.recvfrom(BUFFER_SIZE)
except socket.timeout:
print("Didn't receive data! [Timeout 5s]")
continue