Появилась задача написать клиентский сокет для полинга информации с устройства.

Необходимо залогиниться, считывать информацию и в зависимости от того, что присылает "железка" слать в ответ данные.

Т.к. данные приходят порциями и с интервалами я должен в цикле считывать до конца пакета. Проблема состоит в том, что когда в клиентском сокете вызывается два раза подряд функция recv() то программа зависает. Как можно обойти эту проблему (заставить клиентский сокет считывать recv() несколько раз подряд пока не закончится таймаут или данные)? Что самое интересное в серверном функция recv() работает отлично.

import socket,time

HOST = '192.168.10.99'
PORT = 23

sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect((HOST,PORT))

#блок авторизации
sock.send("enter\n")
sock.send("login\n")
sock.send("password\n")
#конец блока авторизации

sock.send("status\n")


while 1:
    bufsock=sock.recv(1024) # здесь зависает
    if not bufsock:
        break
    print bufsock
    time.sleep(0.2)
#я пробовал заменить цикл while() на несколько подряд идущих sock.recv() но проблема осталась

sock.send("logout\n")

sock.close()
buff = ""
sock.settimeout(0.13)
while True:
    try:
        while True:
            buff += sock.recv(1)
            if isPack(buff): return    # Проверяем целый ли пакет
    except socket.timeout:
        pass    # Проверяем, не нужно ли завершить цикл?
    except socket.error, msg:
        return    # Обрабатываем ошибку сокета
    # Здесь в buff будет целый пакет, делаем с ним много всякого полезного...
    buff = ""    # Отчищаем буфер для слкдующего пакета.
Я у себя именно такой подход и использую.

Last edited April 25, 2008, 5:05 a.m.

...так кто ж ты, наконец?
-- Я -- часть той силы, что вечно хочет зла
и вечно совершает благо.
Спасибо за подробный ответ!
----------
кстати, я пока искал решение проблемы нашел много разной документации по сокетам. Вдруг, кому в будущем понадобится:

Socket Programming HOWTO
мануал Sockets programming in Python
инфа по потокам(для серверного сокета)
gOn
Спасибо за подробный ответ!
У меня там ошибка. Должно быть так:
...
            if isPack(buff): break    # Проверяем целый ли пакет
...
gOn
кстати, я пока искал решение проблемы нашел много разной документации по сокетам. Вдруг, кому в будущем понадобится:
Вот за это спасибо. В тему.
...так кто ж ты, наконец?
-- Я -- часть той силы, что вечно хочет зла
и вечно совершает благо.