Отправка необработанных двоичных данных через сокеты в Python 3

Я работаю над кодированием и декодированием Хаффмана. Я закодировал строку в двоичный файл с использованием алгоритма Хаффмана, и теперь я хочу отправить ее на другой компьютер через сокеты с использованием Python 3, где закодированные данные будут декодированы обратно. Что было бы наиболее эффективным способом сделать это?

Кодирующая часть кода:

import heapq
import socket

class HuffmanEncoder:
    output = {};
    class Node:
        def __init__(self,data,freq,left=None,right=None):
            self.data = data
            self.freq = freq
            self.left = left
            self.right = right

    def __init__(self,root):
        self.root = root

    def isLeaf(root):
        return not root.left and not root.right

    def buildHuffman(p):
        while len(p) != 1:
            left = heapq.heappop(p)[1]
            right = heapq.heappop(p)[1]
            top = HuffmanEncoder.Node('$',left.freq + right.freq)
            top.left = left
            top.right = right
            heapq.heappush(p,(top.freq,top))
        return heapq.heappop(p)[1]

    def printCodes(root,arr,top):
        if root.left:
            arr.insert(top,'0')
            HuffmanEncoder.printCodes(root.left,arr,top + 1)

        if root.right:
            arr.insert(top,'1')
            HuffmanEncoder.printCodes(root.right,arr,top + 1)

        if HuffmanEncoder.isLeaf(root):
            s = ""
            for i in range(0,top):
                s += arr[i]
            HuffmanEncoder.output[root.data] = s
        return HuffmanEncoder.output

def main():
    p = []
    arr = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',' ']
    freq = [8.167,1.492,2.782,4.253,12.702,2.228,2.015,6.094,6.966,0.153,0.772,4.025,2.406,6.749,7.507,1.929,0.095,5.987,6.327,9.056,2.758,0.978,2.360,0.150,1.974,0.074,25.422]
    for i in range(0,len(arr)):
        x = HuffmanEncoder.Node(arr[i],freq[i])
        heapq.heappush(p,(x.freq,x))

    root = HuffmanEncoder.buildHuffman(p)
    arr = []
    top = 0
    codes = HuffmanEncoder.printCodes(root,arr,top)
    for key in sorted(codes):
        print(key,codes[key])
    s = input()
    for i in range(0,len(s)):
        print(codes[s[i]])

if __name__ == '__main__':
                 main()

2 ответа

Посмотрите https://docs.python.org/3/howto/unicode.html при попытке отправить необработанные 8-битные двоичные данные, Python закодирует их перед отправкой через сокет, следуя этому правилу:

"если значение < 128, оно представлено соответствующим байтовым значением. Если значение>= 128, оно превращается в последовательность из двух, трех или четырех байтов, где каждый байт последовательности находится между 128 и 255."

Как только вам удалось преобразовать массив 8-битных данных в строку, отправьте строку с помощью

socket.send_string(yourstring.encode('latin-1')

Вам нужно отправить строковые значения в байт-коде, тогда вы можете сделать: socket.send(byte(message,'utf-8')) Или же socket.send(message.encode())

Если вы хотите отправить простой текст, вы можете отправить его напрямую: b'Spain' но если ваш текст в utf-8 (не ascii), вы должны сделать: 'España'.encode()

Посмотри этот пример клиента и смотри .encode() а также .decode() который использует UTF-8 по умолчанию:

#!/usr/bin/python3
import socket

s = socket.socket()
s.connect(("localhost", 9999))

while True:
    msg = input("> ")
    s.send(msg.encode())
    if msg == "quit":
        break
    received=s.recv(1024)
    print(received.decode())

print("Bye")

s.close()
Другие вопросы по тегам