Форум сайта python.su
Как сделать сокет что б socket.recv(bufsize) мог возвращать None, в случае если ничего нет.
setblocking(0) - Resource temporarily unavailable
setblocking(1) - зависает в ожидании.
settimeout(30) - тоже не то - через 30 секунд возбуждает ошибку: socket.timeout: timed out
Прикол в том что в 2.5 питоне, такой вызов крутится в цикле без всяких исключений в _fileobject.read():
while True:
data = self._sock.recv(recv_size)
if not data:
break
buffers.append(data)
Офлайн
> возбуждает ошибку: socket.timeout: timed out
это нормально, это значит никаких данных не пришло за указанный период, “так все и юзают”
можешь попробовать на селектах, может больше понравиться.
Офлайн
o7412369815963Я мог бы вообще обойтись send, recv. Пишу обёртку для другого класса, где _fileobject почти везде юзается, и вот такая делема, переписывать много и работать в 2.5 или переписывать мало и менять версию.
Офлайн
alexx11
Зависание происходит в ситуации когда размер данных кратен recv_size (например, посылаем 2048 байт, а recv_size 1024). Метод _sock.recv(recv_size) прочитает две порции данных, станет ждать еще, но ничего не получит. В итоге таймаут и исключение.
Есть несколько вариантов решения проблемы:
1. Если известно что пакет будет меньше некоторого размера, например 2 КБ, укажи recv_size = 2048
2. В заголовке пакета первые несколько байт указывают размер данных SIZE. Твой метод read() сперва читает несколько байт, узнает SIZE и затем читает остальное recv(SIZE).
3. Самый распостраненный. В конце пакета передается разделитель, который означает конец пакета. После чтения каждой порции данных проверяем что там в конце.
BUFSIZE = 4096
END = '\r\n\r\n'
def _recv(sock):
r = ''
while 1:
chunk = sock.recv(BUFSIZE)
r += chunk
if r.endswith(END):
return r[:-4]
def _send(sock, data):
sock.send(data + END)
Офлайн
dimabestЯ тоже так всегда считал, но интересно что думали когда 2.5 в релиз сдавали =\
станет ждать еще, но ничего не получит. В итоге таймаут и исключение.
dimabestИнтересно. Но блин, это решение, в котором стандартную библиотеку надо допиливать, а мне это не нравится.
3. Самый распостраненный. В конце пакета передается разделитель, который означает конец пакета. После чтения каждой порции данных проверяем что там в конце.
Офлайн