Как отправить любые данные через python3 сокетов? - PullRequest
0 голосов
/ 13 января 2020

Я новичок в python сокетах и ​​хочу написать send(data: any), который будет обрабатывать любые типы данных через сокет, но есть некоторые проблемы. Я сделал это так:

    def send(self, data: any):
        if type(data) is not bytearray:
            b = bytearray()
            b.extend(map(ord, data))
            self.__s__.sendall(b) # s is the socket
        else:
            self.__s__.sendall(data)
    def recv(self, len_of_packet: int):
        buf = bytearray()
        while len(buf) < len_of_packet:
            buf = buf.append(self.__s__.recv(len_of_packet - len(buf)))
        return buf

но это дает мне

    buf = buf.append(self.__s__.recv(len_of_packet - len(buf)))
TypeError: 'bytes' object cannot be interpreted as an integer

Я сделал это oop в recv(), поскольку сокеты TCP могут отправлять только часть данные я также сделал if type(data) is not bytearray:, потому что sendall() хочет только байты, но по какой-то причине это не работает. Я пытался использовать bytes(), но были другие ошибки. Итак, какой самый pythoni c способ отправить любые данные и получить их на другом конце? Особенно я хочу отправить картинки и текст. И как обработать тот факт, что recv() возвращает str (), который я хочу быть байтами?

Пример вызова:

image = open('image.jpg', 'rb').read()
con.send(image)

, а на другом конце:

image = con.recv(size)

Ответы [ 2 ]

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

Вы неправильно интерпретируете, как работает bytearray.append ():

help (bytearray.append)

B.append(int) -> None

Добавьте один элемент к конец B.

Вы хотите использовать bytearray.extend ():

help (bytearray.extend)

B.extend(iterable int) -> None

Добавьте все элементы из итератора или последовательности в конец B.

Есть несколько других проблем с вашим кодом. Например, recv TCP-сокета вернет пустой байтовый массив после закрытия соединения. В этом случае у вас будет бесконечное число l oop, если соединение было разорвано преждевременно.

0 голосов
/ 13 января 2020

Я, вероятно, исправил проблему, сделав такие функции:

def send(self, data: any):
    if type(data) is int:
        data = str(data)
    if type(data) is bytes or type(data) is bytearray:
        self.__s__.sendall(data)
    else:
        b = bytearray()
        b.extend(map(ord, data))
        self.__s__.sendall(b)

def recv(self, len_of_packet: int):
    data = bytearray()
    while len(data) < len_of_packet:
        packet = self.__s__.recv(len_of_packet - len(data))
        if not packet:
            return None
        data.extend(packet)
    return data

По крайней мере, этот код решает мою проблему, потому что я успешно отправил изображение через сокет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...