Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 11, 2007 10:19:20

dorian
От:
Зарегистрирован: 2006-05-18
Сообщения: 79
Репутация: +  0  -
Профиль   Отправить e-mail  

Socket+threading

Возник вопрос при организации многопоточного приложения в работе с сокетами. Имеется сервер, который слушает сокет и при подключении клиента создает на стороне сервера объект клиента (отдельной нити естесно). Этот объект начинает самостоятельно отслеживать сокет соединение.
Вот выдержки из кода:

def run(self):
“старт объекта клиента”
while 1:
data = self.get()
if data:
self._appManager.InvokeApp(data)

def get(self):
“слушаем клиента и принимаем от него данные”
data = ‘'
try:
while 1:
zipData = self._data_socket.recv(4)
if zipData == ’' :
break
data = data+zipData
except:
self._logger.critical('Error while recieving package from client')
self.__del__()
self._logger.info('Get data complete succesful')
return pickle.loads(zlib.decompress(data))

проблемы возникают в методе get в цикле который принимает данные. После того как пакет полностью передался, выход из цикла не происходит, а просто recv ожидает следующего пакета. В доке http://www.amk.ca/python/howto/sockets/ сказано, что для решения этой проблемы необходимо передавать длину пакета. Но возможно существуют иные методы решения?



Офлайн

#2 Янв. 11, 2007 10:36:16

Viper
От:
Зарегистрирован: 2006-11-08
Сообщения: 137
Репутация: +  0  -
Профиль   Отправить e-mail  

Socket+threading

Возможны несколько вариантов:
передавать длинну пакета,
передавать признак конца,
после передачи клиент закрывает конект.



Офлайн

#3 Янв. 11, 2007 10:55:31

dorian
От:
Зарегистрирован: 2006-05-18
Сообщения: 79
Репутация: +  0  -
Профиль   Отправить e-mail  

Socket+threading

Последний вариант наверняка не подходит потомучто мне необходимо удерживать соединение до тех пор, пока клиент не закроет приложение.
Второй вариант тоже не особо подходит, потому как данные компресятся и передаются в серелизированной форме, поэтому там могут быть какие угодно символы и наверняка подобрать символ завершения пакета не удастся. Я могу конечно ошибаться.
Используя первый вариант, как можна передать длину пакета, если я как уже писал, передаю данные в последовательной форме в заархивированном виде?



Офлайн

#4 Янв. 11, 2007 18:32:31

Viper
От:
Зарегистрирован: 2006-11-08
Сообщения: 137
Репутация: +  0  -
Профиль   Отправить e-mail  

Socket+threading

Можно, например, перед твоими запакованными данными вставлять сериализованный, но не запакованный, int.



Офлайн

#5 Янв. 12, 2007 09:03:33

dorian
От:
Зарегистрирован: 2006-05-18
Сообщения: 79
Репутация: +  0  -
Профиль   Отправить e-mail  

Socket+threading

Уже так и сделал, спасибо



Офлайн

#6 Янв. 22, 2007 23:50:51

seven
От:
Зарегистрирован: 2007-01-22
Сообщения: 1
Репутация: +  0  -
Профиль   Отправить e-mail  

Socket+threading

Здравствуйте у меня такая проблема. Надо написать бота который бы обходит веб-страницы и сохранял бы их.
Есть массив запросов.
queries -> GET /index.php?id=0
queries -> GET /index.php?id=1

queries -> GET /index.php?id=10

есть ф-ция получения страниц по запросу через прокси:

def get_page(proxy,port,header):
page='' #Полученная страница
buff='1';
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((proxy,port))
sock.send(header)
while buff:
buff=sock.recv(1024)
if buff:
page+=buff

sock.close()
return(page)
Проблема в том чтобы переписать ее так чтобы он ее использовать в n потоков. Помогите пожалуйста. Заранее благодарен.



Отредактировано (Янв. 22, 2007 23:51:17)

Офлайн

#8 Янв. 23, 2007 09:48:22

dorian
От:
Зарегистрирован: 2006-05-18
Сообщения: 79
Репутация: +  0  -
Профиль   Отправить e-mail  

Socket+threading

На мой взгляд идея примерно такова:
pages # список объектов страниц
#наполняем список объектами
for query in queries:
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((proxy,port))
pages.append(Page(sock, header))
pages.setDaemon(1)
# стартуем нить
pages.start()



class Page(threading.Thread)
def __init__(self, dataSocket, header):
threading.Thread.__init__(self, name='pageThread')
self._dataSocket = dataSocket
self._pageContent = ''
self._header = header
self._complete = False # завершение обработки

def run(self):
“переопределяем run”
self._dataSocket.send(self._header)
while buff:
buff=self._dataSocket.recv(1024)
if buff:
self._pageContent+=buff
self._complete = True

def __del__(self):
“грохнуть объект”
self._dataSocket.close()
thread.exit()


В коде могут быть ошибки, писал по быстрому =)



Отредактировано (Янв. 23, 2007 09:56:15)

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version