Каков наилучший способ собрать байты, отправленные с клиента на сервер? - PullRequest
0 голосов
/ 16 января 2020

Каков наилучший способ потоковой передачи байтов от клиента к серверу кусками определенного размера?

Сейчас я кодирую аудиофайл с помощью base64, затем сжимаю его с помощью zlib и отправляю через сокет-соединение. Моя проблема заключается в попытке восстановить оригинал на сервере.

Я думал и тестировал, используя пустую строку, которая добавляется со всеми байтами, которые получает сервер. Казалось, все в порядке, но в начале сохранялась буква «b», из-за чего он не мог восстановить исходный аудиофайл.

Я только что попытался декодировать байты и удалить «b» из начало и "" "от конца (данные [2: -1]) каждого набора строк, полученных сервером, но это отрезало несколько символов от оригинала.

сторона клиента:

with open(arquivo, 'rb') as input_file:
   abc = base64.b64encode(input_file.read())

try1 = zlib.compress(abc)

n = 338
result = [try1[i:i+n] for i in range(0, len(try1), n)]

HOST = ''
PORT = 9999

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.connect((HOST,PORT))

i = 0

for item in result:
    item = str(item)
    print(item)
    s.send(item.encode())
    i += 1
    print('i = ', i)
    time.sleep(2)

Сторона сервера:

HOST = ''
PORT = 9999

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

print('Servidor Inicializado')
s.bind((HOST,PORT))
s.listen()
audiofile = ''
i = 0
conn, addr = s.accept()



while True:


    data1 = conn.recv(2048)
    print('data1 undecoded = ', data1)
    text = data1.decode()

    data = text[2:-1]
    print('data EDITADO = ', data)

    audiofile = audiofile + data
    i += 1
    print('i = ', i)
    print('audiofile = ', audiofile)

    if not data:
        print('No Data Received!')

    print('Recebeu tratado :', data)

Не знаю, как поступить, любая помощь приветствуется. Спасибо!

1 Ответ

1 голос
/ 16 января 2020

Вот пример того, как я отправляю и получаю данные с помощью сокетов.

Как правило, я их собираю. Если вы не знакомы с pickle, он используется для сериализации python объектов для хранения или отправки по таким соединениям, как сокеты.

Сторона клиента:

import pickle

with open(arquivo, 'rb') as input_file:
   abc = base64.b64encode(input_file.read())
# I haven't used these libraries so I'm assuming you know how to unpack it from here
try1 = zlib.compress(abc)

HOST = ''
PORT = 9999

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.connect((HOST,PORT))

# serialize the python object 
message = pickle.dumps(try1)

# get the length of the pickled object
length = len(message)
# convert into a fixed width string
length = str(length).rjust(8, '0')
# send the length of the object we will send
s.sendall(bytes(length, 'utf-8'))

# send the object
self.client.sendall(message)

Сторона сервера:

import pickle

HOST = ''
PORT = 9999

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

s.bind((HOST,PORT))
s.listen()

conn, addr = s.accept()

# get the length of the object we are about to receive
length = conn.recv(8)
# turn it back into an int
length = int(length.decode('utf-8'))

# I keep this to determine if we've received everything or not
full_length = length
message = None

# loop until we've zeroed out our length
while length > 0:
    # only receive what we need
    # at a maximum of 128 bit chunks
    chunk_len = min(128, length)

    length -= chunk_len

    chunk = conn.recv(chunk_len)
    if message is None:
        message = chunk
    else:
        message = message + chunk

# Edit: I've had issues with slow connections not receiving the full data
# for those cases adding something like this works
while len(message) < full_length:
    chunk_len = min(128, full_length - len(message))
    chunk = conn.recv(chunk_len)
    message = message + chunk

# now that we've received everything, we turn it back into a python object
try1 = pickle.loads(message)

# this should be the same try1 you sent

Отказ от ответственности: я не проверял ничего из этого, и при этом я не знаю, что такое объект try1 или что вы хотите с ним делать. это просто получение его из точки а в точку б.

...