Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 26, 2010 12:03:09

nauman
От:
Зарегистрирован: 2009-10-28
Сообщения: 50
Репутация: +  0  -
Профиль   Отправить e-mail  

socket и Линукс

Просветите пожалуйста. Есть скрипт сервер и клиент, соединение через сокет. Серверная часть работает на Виндовс XP. Суть проблемы скрипт клиент полностью работает только под виндой ХР, под Линуксом появляется ошибка. Сразу оговорюсь, думаю, что проблема в линуксе, каоето ограничение, так как с разных машин получаю один и тотже размер 1448. Привожу пример:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.0.24', 54917))
print 'Serv on address: ', s.getpeername()
for i in range(3):
content = s.recv(300000)
print len(content)
ima=Image.open(StringIO.StringIO(content)).quantize(colors=96, method=1)
Serv on address:  ('192.168.0.24', 54917)
1448
Traceback (most recent call last):
File "/media/truecrypt1/socket_client.py", line 20, in <module>
ima=Image.open(StringIO.StringIO(content)).quantize(colors=96, method=1)
File "/usr/lib/python2.6/dist-packages/PIL/Image.py", line 717, in quantize
self.load()
File "/usr/lib/python2.6/dist-packages/PIL/ImageFile.py", line 198, in load
s = read(self.decodermaxblock)
File "/usr/lib/python2.6/dist-packages/PIL/PngImagePlugin.py", line 391, in load_read
cid, pos, len = self.png.read()
File "/usr/lib/python2.6/dist-packages/PIL/PngImagePlugin.py", line 96, in read
len = i32(s)
File "/usr/lib/python2.6/dist-packages/PIL/PngImagePlugin.py", line 44, in i32
return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24)
IndexError: string index out of range
Этот код нормально работет под виндой XP, под Ububtu 10.04 c выше описанной ошибкой. В обоих случаях Python 2.6.



Отредактировано (Авг. 26, 2010 20:11:24)

Офлайн

#2 Авг. 26, 2010 19:19:31

tmp_a6367100
От:
Зарегистрирован: 2010-08-23
Сообщения: 46
Репутация: +  0  -
Профиль   Отправить e-mail  

socket и Линукс

Суть проблемы скрипт клиент полностью работает только под виндой ХР, под Линуксом появляется ошибка.
:-)

если это единственная информация которая нам доступна – то это малова-то



Офлайн

#3 Авг. 26, 2010 19:28:52

tmp_a6367100
От:
Зарегистрирован: 2010-08-23
Сообщения: 46
Репутация: +  0  -
Профиль   Отправить e-mail  

socket и Линукс

что находиться на строчке 20 ? в приведённом вами коде нет никаких

ima=Image.open(StringIO.StringIO(content)).quantize(colors=96, method=1)
но ошибка именно там…

********************************************************************************

..и вообще – зачем вы делаете – s.recv(300000) ?

вы используете слишком низкоуровневые операции на сокетах!


операции могут быть и на порядок выше .

********************************************************************************

и вообще:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # плакал IPv6 горькими слезами, 
# ... потомучто злой хзяин (программист) забыл выполнить http://docs.python.org/library/socket.html#socket.getaddrinfo
(но это уже не относитсья к проблеме)



Офлайн

#4 Авг. 26, 2010 19:36:41

tmp_a6367100
От:
Зарегистрирован: 2010-08-23
Сообщения: 46
Репутация: +  0  -
Профиль   Отправить e-mail  

socket и Линукс

tmp_a6367100
операции могут быть и на порядок выше .
затем делайте http://docs.python.org/library/stdtypes.html#file.read или сразу подставляйте файловый-объект внутрь нужной функции



Отредактировано (Авг. 26, 2010 19:38:08)

Офлайн

#5 Авг. 26, 2010 20:06:58

nauman
От:
Зарегистрирован: 2009-10-28
Сообщения: 50
Репутация: +  0  -
Профиль   Отправить e-mail  

socket и Линукс

tmp_a6367100
что находиться на строчке 20 ? в приведённом вами коде нет никаких
Код:

ima=Image.open(StringIO.StringIO(content)).quantize(colors=96, method=1)

но ошибка именно там…
Ошибка там только потому, что Image получает не полную, урезанную возможно Линуксом, информацию. Этот же скрипт под виндой работает без исключений. 1448 - это количество знаков в получаемой строке, при любом раскладе. На самом деле их передается больше. Для ясности картины чуть изменил первый пост. ima, ему присваивается объект Image, далее пишется в файл на диск. Объект передается не весь поэтому он сообщает это в листинге возникших исключений.
tmp_a6367100
Т.е. вы предлагаете последовательно получать по 1448 символов, пока не получит всю строку?
Это может и быть выходом в данной проблеме, но все же, хотелось бы узнать как убрать ограничение OC.

IPv6 мне в данном случае вообще не нужен.
Серверную часть менять уже не могу.



Отредактировано (Авг. 26, 2010 20:48:13)

Офлайн

#6 Авг. 26, 2010 21:08:20

tmp_a6367100
От:
Зарегистрирован: 2010-08-23
Сообщения: 46
Репутация: +  0  -
Профиль   Отправить e-mail  

socket и Линукс

nauman
IPv6 мне в данном случае вообще не нужен.
пользователей вашей программы пожалейте :-)



Офлайн

#7 Авг. 26, 2010 21:11:53

tmp_a6367100
От:
Зарегистрирован: 2010-08-23
Сообщения: 46
Репутация: +  0  -
Профиль   Отправить e-mail  

socket и Линукс

> Т.е. вы предлагаете последовательно получать по 1448 символов, пока не получит всю строку?

да. так как вы s.recv – это НИЗКОУРОВНЕВАЯ операция…

тоесть если хотите использовать именно эту функцию то нужно возиться с “атамими и малекулами” (в переносном смысле) :-)


> Это может и быть выходом в данной проблеме, но все же, хотелось бы узнать как убрать ограничение OC.

это не ограничение ОС, а правильная её работа.. непонимаю что тут убирать… recv() не обязана получать столько байт сколько вы хотите .

если хотите получать именно столько байт сколько заказываете получать – то используйте другие функции . например как уже писал выше:

f = s.makefile(“rb”)
content = f.read(300000)



Офлайн

#8 Авг. 26, 2010 21:20:17

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

socket и Линукс

Суть проблемы скрипт клиент полностью работает только под виндой ХР, под Линуксом появляется ошибка.
Когда скрипт клиент успешно работает, то он запускается на той же виндовой машине, что и сервер? Если да, то попробуйте запустить его на другой виндовой машине.
Каков размер передаваемых данных с сервера клиенту? В вашем случае это content, какова его длина?



Отредактировано (Авг. 26, 2010 21:21:07)

Офлайн

#9 Авг. 26, 2010 21:34:20

nauman
От:
Зарегистрирован: 2009-10-28
Сообщения: 50
Репутация: +  0  -
Профиль   Отправить e-mail  

socket и Линукс

Ed
Суть проблемы скрипт клиент полностью работает только под виндой ХР, под Линуксом появляется ошибка.
Когда скрипт клиент успешно работает, то он запускается на той же виндовой машине, что и сервер? Если да, то попробуйте запустить его на другой виндовой машине.
Каков размер передаваемых данных с сервера клиенту? В вашем случае это content, какова его длина?
Серверная часть работает на нескольких удаленных компах в пределах локальной сети, везде стоит XP.
Создается скриншёт экрана, и передается по сети к клиенту, размер от файла к файлу отличаетя, в среднем это 70 Кб. Под линуксом к клиенту поступает строго 1448. Кстати проделывал это на гостевой winXP под VirtualBox в том же Ubuntu, результат тотже, линукс рубит размер. На всякий случай фаервол отключал.



Отредактировано (Авг. 26, 2010 22:06:24)

Офлайн

#10 Авг. 26, 2010 22:26:15

Kogrom
От:
Зарегистрирован: 2009-12-03
Сообщения: 160
Репутация: +  0  -
Профиль   Отправить e-mail  

socket и Линукс

Пытался разобраться…
Можно пытаться увеличить буфер:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
SEND_NUMBER = 300000
s.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, SEND_NUMBER)
s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, SEND_NUMBER)
Правда, у меня с ходу вышло увеличить только до 262144 байт.

А вообще, читайте статьи, типа:

http://www.ibm.com/developerworks/ru/library/l-hisock/

вроде бы там говорится, как ещё больше увеличить буфер.

Когда у меня не было под рукой документации и надо было такое считать, то я действовал с помощью склейки, посылая (и принимая) кадры по 256 байт. Первый байт нес в себе размер кадра. Правда я грешил на слабость uCLinux…



Отредактировано (Авг. 26, 2010 22:27:42)

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version