Уведомления

Группа в Telegram: @pythonsu

#1 Июль 26, 2017 15:29:25

fil1111
Зарегистрирован: 2017-07-26
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Socket.timeout при повторном recv()

Python 3.5 Windows

Есть некая железка на микроконтроллере , работающая по TCP/IP , на ней используется LWIP.
Принцип ее работы прост - получает команду (256 байт ) - отдает ответ (256 байт)
В этом режиме все хорошо, и никаких проблем и вопросов.
Но есть часть команд, по которым железка отдает текущие данные , то есть сначала выстреливает заголовок (256 байт) , потом миллисекундная пауза и она начинает отдавать текущие данные по мере поступления, предопределенной ранее в команде длины, весь процесс может занимать до нескольких минут. Пока железка в режиме отдачи текущих данных - на другие команды не реагирует. В Дельфях и C# никаких проблем , получаю событие WSocket1DataAvailable в нем делаю Len := WSocket1.Receive(…) имею текущий буфер и его длину, могу по мере поступления данных их отображать.

В Питоне же могу получить только первый recv() - получаю всегда заголовок, вне зависимости от того что в параметрах recv() 256 байт, все последующие recv или recv_into вылетают с socket.timeout.

conn = socket.socket()
conn.settimeout( 2.0)
conn.connect( (IP, PORT) )

# до этого места могу сколько угодно раз сделать
#conn.send(buffer_out)
#s1=conn.recv(256)
#c командами на ответ по 256 байт - все работает

# в buffer_out команда
conn.send(buffer_out)

s1=conn.recv(256) # заголовок принимается , даже если s1=conn.recv(1024) получаю 256 байт
buffer_in = bytearray(TotalByte)
view = memoryview(buffer_in)
while TotalByte:
try:
nbytes = conn.recv_into(view, TotalByte)
except socket.timeout:
print ('Socket timeout')
continue
except:
traceback.print_exc()
print ('Socket err,)
break
view = view[nbytes:]
TotalByte -= nbytes

просто s2=recv(1024) пробовал . То же самое.
Понятно что просто Питона не знаю. Как написать правильно?

Отредактировано fil1111 (Июль 26, 2017 15:40:20)

Офлайн

#2 Июль 26, 2017 17:15:44

vic57
Зарегистрирован: 2015-07-07
Сообщения: 913
Репутация: +  127  -
Профиль  

Socket.timeout при повторном recv()

ЕМНИП socket.settimeout ставится однократно
https://andreymal.org/21

Офлайн

#3 Июль 26, 2017 17:23:58

fil1111
Зарегистрирован: 2017-07-26
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Socket.timeout при повторном recv()

Однократно и ставлю - после создания.

Офлайн

#4 Июль 26, 2017 17:34:49

vic57
Зарегистрирован: 2015-07-07
Сообщения: 913
Репутация: +  127  -
Профиль  

Socket.timeout при повторном recv()

fil1111
Однократно и ставлю - после создания.
так сделайте его сколько вам надо. не помню точно, но вроде надо на каждый recv ставить
 while TotalByte:
        try:
            nbytes = conn.recv_into(view, TotalByte)
            print(conn.gettimeout())# check timeout
если знаете размер ответа, можно проще
 #!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import time
sock = socket.socket()
sock.connect(('localhost', 8000))
count = 1024
while count > 0:
    data = sock.recv(1024)
    if data:
        count -= len(data)
        print count,data
    time.sleep(1)
sock.close()

Отредактировано vic57 (Июль 26, 2017 21:40:46)

Офлайн

#5 Июль 27, 2017 11:06:44

fil1111
Зарегистрирован: 2017-07-26
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Socket.timeout при повторном recv()

Засунул сокет в поток - все чудесным образом заработало.
Впрочем, все равно собирался.
Ну и причина любому Windows-ятнику должна быть понятна )

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version