Оказалось, что мое использование struct.pack было прекрасным. Я просто использовал неправильные переменные из-за ошибок копирования/вставки. Не забудьте следить за такими ошибками в своем собственном коде!Python: ошибки с struct.pack в разных целях
Оригинальный вопрос ниже, если вы хотите его увидеть.
Мне нужно отправить две различные части информации в виде полезных данных по UDP-пакетам. Эти пакеты содержат информацию о месте назначения объекта (то есть IP-адрес получателя и номер порта назначения). Я уже подтвердил другими методами, что я собираю правильную информацию. Где моя проблема заключается в расшифровке информации после ее отправки. Вот информация закодировать, и метод, используемый для их кодирования:
IP-адрес: xxx.xxx.xxx.xxx (ххх любое число от 0 до 255)
IP-адрес разделяется на список из четырех чисел.
Список четырех чисел упакован с использованием struct.struct ('4B'), где каждый байт является одним из номеров списков.
на приемном конце, это будет получен и распаковано с помощью идентичных struct.struct («4В»)
строки, представляющей IP-адрес восстанавливается с помощью четыре распакованных значений и должным образом размещены периодов.
и номер порта:
Номер порта: одним целое число, как правило, в тысячах (т. Е 8000, мой тест значение)
Хранится с использованием struct.struct («Н») (это 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: Никогда не обращайте внимания на эту проблему раньше, я сделал более глупые ошибки с использованием неправильных переменных.
не связаны: вы можете кодировать/декодировать IP для передачи по сети с помощью 'socket.inet_aton()/.inet_ntoa() '. – jfs