Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 5, 2016 18:22:34

darwol
Зарегистрирован: 2016-10-05
Сообщения: 1
Репутация: +  0  -
Профиль   Отправить e-mail  

Преобразовать строку в байты

Здравствуйте все. Уже второй день никак не могу решить одну задачу, понимаю, что всё просто и понимаю, что код мой корявый, но из открытых пары десятков вкладок решения так и не нашел, поэтому прошу помощи… Суть в том, что мне нужно принимать энное количество байт от сервера и записывать в файл определенного формата.
Я создаю соккет, подключаюсь к серверу, принимаю данные в список, потом конвертирую список в строку. Далее формирую строку хедера для файла, после чего приклеиваю строку хедера к строке данных и записываю всё это в файл и наблюдаю такую картину: хедер находится в начале файла, но не в виде байтов, а как текст… То есть хедер выглядит так: 0xbad4feed0x125e773c1120x7d170x400 и он просто текстом написан в начале бинарника…

 #!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import socket
import time
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('192.168.1.58', 32023))
y = 0
buffr = 0
data = []
while y  < 65536:
	buffr = sock.recv(1024)
	x = sys.getsizeof(buffr)
	y = x + y
	data.append(buffr)
current_milli_time = lambda: int(round(time.time() * 1000))
pre_head = ''.join(hex(0xBAD4FEED) + hex(current_milli_time()) + hex(32023) + hex(1024))
pre_data = ''.join(data)
head = pre_head.replace('L','')
head = head.encode("utf-8")
flush = head + pre_data
my_file = open("tcp.slf", 'ab')
my_file.write(flush)
my_file.close()
sock.close()

Буду благодарен за науку )

Отредактировано darwol (Окт. 6, 2016 11:46:39)

Офлайн

#2 Окт. 7, 2016 03:15:10

scidam
Зарегистрирован: 2016-06-15
Сообщения: 288
Репутация: +  35  -
Профиль   Отправить e-mail  

Преобразовать строку в байты

Здесь много зависит еще от версии Python'a, так, например, начиная с Python3.2 у int-типа есть метод to_bytes, который упрощает жизнь.
Будем, однако, считать, что у нас, что-то вродe Py2.7+
Сначала создадим вспомогательную функцию, которая будет конвертировать наши целые (int) в шестнадцатиричное представление с четной длиной:

 def convert(int_value): 
    encoded = format(int_value, 'x')
    length = len(encoded)   
    encoded = encoded.zfill(length+length%2)
    return encoded

Теперь конструируем ваш header:
 header = 'bad4beef' + convert(current_milli_time()) + convert(32023) + convert(1024)

head = pre_head.replace('L','')
Этого я не понял.

В любом случае, далее создаем массив байтов, который хотим записать в файл:
 tosave = bytearray.fromhex(header) + ''.join(data)

И записываем в файл:
 with open('myfile.dat', 'ab') as f: 
    f.write(tosave)




Отредактировано scidam (Окт. 7, 2016 03:22:52)

Офлайн

#3 Окт. 7, 2016 07:49:47

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Преобразовать строку в байты

scidam
Здесь много зависит еще от версии Python'a,
мне так не кажется
 import struct
data = b"abcd"
head = struct.pack("4I",0xBAD4FEED,33,32023,1024)
with open("x.dat","wb") as f:
    f.write(head)
    f.write(data)

тут только буковка b от питона 3, но и эта разница исчезнет если данные из сокета принимать.



Офлайн

#4 Окт. 7, 2016 08:14:07

scidam
Зарегистрирован: 2016-06-15
Сообщения: 288
Репутация: +  35  -
Профиль   Отправить e-mail  

Преобразовать строку в байты

Пожалуй, это не существенно, но все-таки struct.pack не сможет упаковать большие числа. А convert, определенный выше, на это способен.

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version