2013-11-12 5 views
0

Оказалось, что мое использование struct.pack было прекрасным. Я просто использовал неправильные переменные из-за ошибок копирования/вставки. Не забудьте следить за такими ошибками в своем собственном коде!Python: ошибки с struct.pack в разных целях

Оригинальный вопрос ниже, если вы хотите его увидеть.


Мне нужно отправить две различные части информации в виде полезных данных по UDP-пакетам. Эти пакеты содержат информацию о месте назначения объекта (то есть IP-адрес получателя и номер порта назначения). Я уже подтвердил другими методами, что я собираю правильную информацию. Где моя проблема заключается в расшифровке информации после ее отправки. Вот информация закодировать, и метод, используемый для их кодирования:

IP-адрес: xxx.xxx.xxx.xxx (ххх любое число от 0 до 255)

  1. IP-адрес разделяется на список из четырех чисел.

  2. Список четырех чисел упакован с использованием struct.struct ('4B'), где каждый байт является одним из номеров списков.

  3. на приемном конце, это будет получен и распаковано с помощью идентичных struct.struct («4В»)

  4. строки, представляющей IP-адрес восстанавливается с помощью четыре распакованных значений и должным образом размещены периодов.

и номер порта:

Номер порта: одним целое число, как правило, в тысячах (т. Е 8000, мой тест значение)

  1. Хранится с использованием struct.struct («Н») (это 2-байтовый объект, который будет содержать номер)

  2. распакованы с помощью идентичных struct.struct («H») на приемном конце

Я полагаю, что делаю все правильно до части кодирования, так как проверяю значения до их кодирования и отправки, и они верны. Когда я получаю их на другом конце и расшифровываю их, значения ошибочны, и я не могу понять, почему. Вот пример:

ввода IP и порт:

IP: 164.107.112.70 Порт: 8000

Выход IP и порт:

IP: 64.31.0.0 Порт: 10

Что я могу делать неправильно здесь, чтобы справиться с этими проблемами?

EDIT: Вот несколько кодов в соответствии с запросом.

#pack IP for transport 

#split into four 1-byte values 
SplitIP = IP.split('.') 

#create a 4-byte struct to pack IP, and pack it in remoteIP 
GB = struct.Struct("4B") 

remoteIP = GB.pack(int(SplitIP[0]),int(SplitIP[1]),int(SplitIP[2]),int(SplitIP[3])) 
#remoteIP is now a 4-byte string of packed IP values 


#pack Port for transport 

#create a 2-byte struct to pack port, and pack it in remotePort 
GBC = struct.Struct("H") 

remoteIP = GBC.pack(int(PORT)) #needs another byte 
#remoteIP is now a 2-byte string of packed IP values 


#Join the two parts together 

remoteIP += str(remotePort) 

После этого, некоторые дополнительные элементы упакованы (флаг 1 байт, 1 байт 0/1 значение а для АВР (пока не реализовано) и полезной нагрузки (в данном случае, размер файла целиком в качестве значения 4 байта). Затем они направляются через команду передачи сокета, в другой процесс на той же машине на клиенте, предоставленный номер порта (в моих тестах, 4000 используется).

#get size of file from os command 
filesize = bytearray(4) 
#save as 4-byte string 
filesize = str(os.stat(localfile).st_size) 

#add flag 
flag1 = bytearray(1) 
flag1 = str(1) 

#add zerone 
if(zerone == 0): 
    zerone = 1 
else: 
    zerone = 0 

zeon = str(zerone) 

#package the filesize string 

filesizestr = ''.join(remoteIP) 
filesizestr = filesizestr + flag1 + zeon #now contains 4,2,1,1 byte arrays 

filesizestr += filesize      #now we have complete packet 

s.sendto(filesizestr, ('127.0.0.1', int(TPORT))) 

EDIT : Ошибка была сделана с копией/пастой, поистине общим противником, который необходимо учитывать при каждом повороте кодирования.

The cur проблема с арендой заключается в том, что, хотя IP-адрес теперь отправляется просто отлично, Порт ошибочен.

Отправленное порт был 8000

Принимаемый порт был @ \ x1f

Я не совсем уверен, как интерпретировать этот вывод, если кто-нибудь может помочь мне понять, что случилось, то я бы очень признателен Это. Мое предположение заключается в том, что я либо сделал ошибку кодирования, либо захватил неверные данные. Что касается данных, расположение строки отправленного должно быть:

4 байта для IP, 2 байта для порта и т.д.

Так я хватаю эту информацию со следующими двумя строками:

packedIP = data[0:4] #grab 4-byte IP data 
packedPort = data[4:6] #grab 2-byte port data 

Это правильно, да? Я все еще немного смущен тем, как работают аксессоры строк Python. IP я получил право, хотя, поэтому я думаю, что я в порядке.

EDIT: Никогда не обращайте внимания на эту проблему раньше, я сделал более глупые ошибки с использованием неправильных переменных.

+0

не связаны: вы можете кодировать/декодировать IP для передачи по сети с помощью 'socket.inet_aton()/.inet_ntoa() '. – jfs

ответ

1

Таким образом, в теории байт на проводе должен быть:

A4 6B 70 46 1F 40 

Но то, что вы декодируется, кажется,

40 1F 00 00 00 0A 

Это выглядит подозрительно, что последние два байта первого набора являются первые два байта (обратные) во втором наборе. Можем ли мы увидеть код, который вы используете? Это может помочь определить точную проблему.

Кроме того, являются ли машины маленькими эндианскими или большими концами? Когда я делаю байт-упакованные структуры, я обычно использую упорядочение сети (big endian), что означает, что вы должны префикс строк структуры восклицательным знаком (см. http://docs.python.org/2/library/struct.html).

EDIT: Ваша проблема эта линия:

remoteIP = GBC.pack(int(PORT)) #needs another byte 

должно быть

remotePort = GBC.pack(int(PORT)) #needs another byte 
+0

Я добавил источник, как вы просили. Надеюсь, этого достаточно. Я не уверен в своих потребностях. – user2828965

+0

У вас есть вероятная ошибка копирования/вставки. Вы переписываете 'remoteIP', когда вы кодируете номер порта, вместо установки' remotePort'. – Jud

+0

Ha! Какая глупая ошибка! Я обновил его и расскажу о том, как это происходит. – user2828965

Смежные вопросы