Как установить тайм-аут на метод 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(), но я вижу, что вы явно отклонили это решение в другом ответе.

Ответ 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