Уведомления

Группа в Telegram: @pythonsu

#1 Сен. 29, 2012 16:29:42

protagonist113
Зарегистрирован: 2012-09-29
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

формирование и отправка пакета

Необходимо сформировать пакет вручную и отправить его на сервер.

Отредактировано protagonist113 (Сен. 30, 2012 17:13:54)

Офлайн

#2 Сен. 29, 2012 17:33:45

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

формирование и отправка пакета

http://wiki.python.org/moin/BitManipulation
https://code.google.com/p/python-bitstring/ - должно подойти

Хотя можно обойтись struct.pack() и бинарной арифметикой.

Офлайн

#3 Сен. 29, 2012 18:13:42

protagonist113
Зарегистрирован: 2012-09-29
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

формирование и отправка пакета

reclosedev
спасибо
То есть, насколько я понял первое слово будет вида?

v='0.2456'
f1=0
f2=1
adr='123'
w0=pack(">5sbb9s",v,f1,f2,adr)

Отредактировано protagonist113 (Сен. 29, 2012 18:14:21)

Офлайн

#4 Сен. 29, 2012 18:30:39

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

формирование и отправка пакета

protagonist113
То есть, насколько я понял первое слово будет вида?
А вы не путаете биты с байтами? Этот код не соответствует первоначальному вопросу.

upd:
Если все-таки речь идет о битах, то примерно так:
import struct
 
def packet_hash(packet):
    return sum(struct.unpack('<%dH' % (len(packet)//2), packet)) & 0xFFFF
 
def create_packet(version, flag1, flag2, address, message):
    first_word = (version << 11) | (flag1 << 10) | (flag2 << 9) | address
    packet = struct.pack('<HH%ds' % len(message), 
                         first_word, len(message), message)
    return packet + struct.pack('<H', packet_hash(packet))
 
print repr(create_packet(0x12, 1, 0, 0x1234, 'test'))  # '4\x96\x04\x00test\x1fp'
С хешированием не до конца понял, нужно ли сообщение хэшировать или только первые два слова? Если сообщение, то нужно еще позаботится о выравнивании до двух байт (при 16-ти битных словах).
И еще, при больших сообщениях лучше сделать через StringIO.

Отредактировано reclosedev (Сен. 29, 2012 18:40:23)

Офлайн

#5 Сен. 30, 2012 01:24:47

protagonist113
Зарегистрирован: 2012-09-29
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

формирование и отправка пакета

reclosedev
спасибо
да, сообщение тоже нужно
Вроде разобрался со всем, кроме этого хеша

Офлайн

#6 Сен. 30, 2012 04:39:11

protagonist113
Зарегистрирован: 2012-09-29
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

формирование и отправка пакета

А как выровнять строку до двух байт?
так?

if len(a)%2==1:

Отредактировано protagonist113 (Сен. 30, 2012 04:40:20)

Офлайн

#7 Сен. 30, 2012 11:54:19

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

формирование и отправка пакета

protagonist113
А как выровнять строку до двух байт?
так?
if len(a)%2==1:
Да. Кстати, struct.pack может сам нулевые байты добавить если указать длину больше.
    ...
    message_len = len(message) + len(message) % 2
    packet = struct.pack('<HH%ds' % message_len, 
                         first_word, message_len, message)
    ...
Только как сервер воспримет такие сообщения? Что это за протокол? Уверены, что хэш - это сумма двухбайтовых слов?

Офлайн

#8 Сен. 30, 2012 12:57:13

protagonist113
Зарегистрирован: 2012-09-29
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

формирование и отправка пакета

reclosedev
Слова считаются как целые 16-разрядные
хеш - сумма 2-х слов заголовка и сообщения

Офлайн

#9 Сен. 30, 2012 14:48:06

unself
Зарегистрирован: 2012-09-30
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

формирование и отправка пакета

reclosedev, разрешите мы Вас еще помучаем. При распаковке готового пакета Питон ругается на выравнивание до 4 байт:

Пакет формируется так

str = "some string"
strLength =  len(str)
needPadding = strLength & 3
if needPadding: strLength += 4 - needPadding
packet = struct.pack(">i%ds" % strLength,  strLength, str)

Читаю данные примерно следующим образом
size = int(struct.unpack(">i", packet))

unpack requires a string argument of length 4

Отредактировано unself (Сен. 30, 2012 15:05:13)

Офлайн

#10 Сен. 30, 2012 17:07:28

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

формирование и отправка пакета

unself
При распаковке готового пакета Питон ругается на выравнивание до 4 байт:
unself
unpack requires a string argument of length 4
Он не на выравнивание ругается
The string must contain exactly the amount of data required by the format (len(string) must equal calcsize(fmt)).
size = struct.unpack(">i", packet[:4])[0]
size, message = struct.unpack(">i%ds" % size, packet)
Мне вот интересно, что вы будете с нулевыми байтами в сообщении делать? В Питоне они не означают конец строки.

Отредактировано reclosedev (Сен. 30, 2012 17:08:47)

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version