Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 9, 2023 20:28:39

SeyranG
Зарегистрирован: 2021-12-03
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

разбор массива байт на пакеты

очередная проблема с массивами байт. Получаю по сети пакет в 1544 байт

         dataF = tcp_socket.recv(1544)
        if(len(dataF) > 0):
            data+=dataF
            i +=1;
            print('Recived ' + repr(len(dataF)) + ' bytes')
            print('In buffer ' + repr(len(data)) + ' bytes')
            if ((i == 3) and (len(data) != 1544)):
                my_bytes = bytearray(data)
                print(my_bytes.hex())
                data = bytes([])
                t0 = time.time()
            if(len(data) == 1544):
                my_bytes = bytearray(data)
                print(my_bytes.hex())
                draw_frame(my_bytes, t0)
                data = bytes([])
                t0 = time.time()

в итоге получается что по сети я получаю не целиком пакет, а в 3 приема. Но это не проблема. Проблема в том что данные в пакетах смещены и начало реального пакета данных оказывается где то в середине получаемого набора данных. Правильный пакет начинается с двух байт 0x5A .
Вот пример полученных данных:

0b250b380b230b2d0b2d0b320b3e0b490b6c0b5e0b640b5e0b6b0b500b670b660b5f0b700b960bf10bbf0be70bc70b220cfa0be90bde0b2c0c0f0c420b3a0b7d0b9a0b330b2b0b470b430b4b0b230b960b420b670b6b0b630b730b600b6c0b580b660b620b880bca0beb0bd40bdd0bfb0b270c140c060c4a0c700c360b540b5b0b430b360b1c0b450b320b4e0b2e0b670b5e0b660b7f0b470bab0b760b720b740b390b920b8c0b150c090c1c0cf80b200c1d0c9e0c4e0c940c8d0c0e0b070b700b3d0b230b400b1b0b440b5a0b580b640b800b780bb80b850b830b740b800b820b700b800bc40b0e0c150c180c460c500c790c5b0cb10cba0cf30cf90d8d69
5a5a02061a0bda0a0c0bf80aec0af00a050b0b0bef0af50a580b1e0b730b7c0b9c0b930bbc0b4f0b9d0b4a0b570b780b520b920b3f0b4a0b8a0b8b0b3c0b4a0b610bd70bf40a0b0b1a0b210be20adc0ae20a110b0a0b270b070b4e0b680b690b9f0bd20b860b890b860b8b0b4c0b7c0b650b810b610b960b5a0b5d0b540b5c0b400b800bdd0af10a060b1d0b280be50a220bf10a350bdf0aef0a310b260b480b8a0bc50b7b0b880b850b710b490b780b4c0b5d0b710b5e0b940b400b990b670b370b410bd10af30a0d0b200bee0aed0a240b0d0bda0af80a2d0bfb0a290b350b5e0b910b8f0b860b850b990b980b680b860b880b6e0b5b0b8f0b980b6e0b660b300b5c0bd20add0ac70acb0a0a0bd00a0d0bd20adb0ae20a340b290b1e0b440b620b7b0b730b850b8c0b3e0b940b7a0b5b0b6a0b630b570b570b890b5c0b8b0bbc0b530beb0add0ae80a130b0e0bb70ad20a250bf70a040b240b080b420b340b4e0b560b930b600b640b520b360b570b5b0b800b510b470b820b6d0b5b0b410b430bb30b110be00a330bfb0abe0ac30ad70ad60aec0a330bf70a0a0b0f0bf30a540b4e0b6d0b490b540b7b0b4c0b550b3a0b6d0b380b550b420b540b2d0b590b840b740bb60af80af60a150b050bd70ab70a110bde0afc0af50a3f0b1d0b0f0b3a0b4d0b480b6c0b830b870b700b540b6c0b670b5d0b740b8c0b7c0b7b0b3e0b540b740bbe0aa80a100be60ac10ae10ac40a010be60ad90afb0a030bf40a170b2a0b400b290b350b510b850b3e0b4e0b510b4d0b590b420b830b700b7b0b4b0b890b7b0bdd0aeb0ad30aeb0afc0acf0ac40ade0ad40aec0ad40a060bf20a290b380b3d0b480b510b4f0b660b6a0b3c0b5d0b450b7a0b730b780b7c0b790b820b800b7b0be20afb0ac60acd0af20ac30a220be30ad10add0afb0ae50a260bf80a110b380b1b0b170b4f0b380b570b5e0b480b8d0b3e0b7a0b660ba50ba90b8b0b770b8e0bcc0a090bf00a090be00abe0aea0ae30ad30acc0ad70a130bf50a050bfa0a470b2c0b390b260b540b430b350b420b670b270b740b860b7d0b820b6d0b590b990b0f0bd90a270b140beb0acd0a020bfb0ade0aea0a170be30af00adb0a480b300b380b370b4e0b760b5e0b6d0b6d0b4e0b630b630b850b550b790b850b980b840bcb0adc0aff0a4c0b000bfe0aef0afe0aed0af40af20a240b0c0bfb0a100b570b150b260b3a0b730b700b530b340b5d0b510b5c0b470b8a0b8a0b680ba50bd70bc70ae30af90a320b2e0b130b270b210bfc0a220b130b160b2f0b170b320b410b520b500b5c0b910b530b500b430b4f0b5b0b690b600b880b820b850b860b8d0bf60aeb0afd0a460b2d0b5b0b380b370bfc0a1e0b430b370b0d0b390b1f0b3b0b4f0b5e0b9a0b7c0b8e0b7d0b740b6b0b7c0b730b8c0bab0bb70ba10bab0b7f0b500b100b260b2e0b550b710b590b360b500b380b5e0b620b6f0b130b4e0b450b770b490b820b880b690b860b
7f0b880b860b830b940b9d0bc40b9f0b9b0b9b0b3e0b320b4f0b590b540b620b570b650b4b0b270b480b290b3c0b760b3c0b400b560b9c0b8c0b850b760b8f0b970b960b910bd50b7f0bcd0b990ba90bba0be50b380b720b710b7c0b3d0b570b690b5f0b330b550b750b620b420b310b250b420b830b550b5e0b830b8e0bc00bbe0b990bd80bc10bb20be20bc70ba60b140cd30b670bf10a590b5b0b4d0b5a0b540b750b450b550b600b750b530b650b560b6c0b3a0b540b7c0b820bbe0b970bca0be10be00bdc0bd70bf30bd30bd60b0a0c100c6f0b5e0b400b250b2f0b230b370b2d0b4c0b3e0b510b6c0b660b640b660b6b0b470b670b6e0b5f0bad0b960bd60bbf0bef0bc70b180cfa0b070cde0b0d0c0f0c420b5d0b7d0b510b330b480b470b3a0b4b0b3d0b960b6e0b670b500b630b9c0b600b520b580b910b620b6d0bca0bf40bd40bf80bfb0b310c140ce80b4a0c500c150b540b510b430b400b1c0b270b320b440b2e0b700b5e0b5d0b7f0b610bab0b900b720b580b390b760b8c0bd40b090cda0bf80b520c1d0c6c0c4e0ca00c8d0c0e0b150b700b490b230b4a0b1b0b890b5a0b600b640bad0b780b9c0b850bc00b740b880b820bc00b800bcc0b0e0c0b0c180c3c0c500c830c5b0ca70cba0cd30cfb0d716b
5a5a02061a0bdc0a0c0bc60aec0aab0a050bca0aef0a370b580b360b730b6a0b9c0b820bbc0b780b9d0b380b570b660b520b690b3f0b4c0b8a0b5d0b3c0b650b610ba20b130b0b0b360b210be40adc0acd0a110be20a270b090b4e0b570b690b7a0bd20b610b890b4e0b8b0b760b7c0b3d0b810b630b960b8b0b5d0b260b5c0b5d0b800bdd0a0d0b060bef0a280b120b220bf30a350b080bef0a200b260b5c0b8a0b900b7b0b660b850b610b490b670b4c0b5f0b710b4c0b940b6f0b990b980b370b5d0b080bf30ae00a200bf00aed0ad30a0d0b040bf80a2f0bfb0a3e0b350b600b910b7f0b860b620b990b3f0b680b600b880b480b5b0b660b980b700b660b640b5c0bd20adf0ac70ae40a0a0bd20a0d0bc00adb0af70a340b070b1e0b350b620b5a0b730b760b8c0b400b940b460b5b0b590b630b450b570b620b5c0b4b0bbc0b6e0b060bdd0ad40a130be70ab70ae80a250bc20a040b140b080b210b340b3f0b560b840b600b660b520b6e0b570b4b0b800b530b470b5c0b6d0b720b410b460bb30b110bb40a330bbe0abe0aed0ad70aeb0aec0add0af70aea0a0f0b4b0b540b500b6d0b6e0b540b490b4c0b450b3a0b390b380b6a0b420b6a0b2d0b5c0b840b480b160bf80acd0a150bf40ad70acc0a110bce0afc0ac20a3f0b0e0b0f0b2b0b4d0b5b0b6c0b520b870b500b540b150b670b840b740b680b7c0b680b3e0b6d0b740bbe0ad70a100baa0ac10aaa0ac40ab90ae60aed0afb0af40af40a090b2a0b530b290b480b510b650b3e0b3f0b510b2c0b590b690b830b850b7b0b760b890b3b0bf60aeb0ad60aeb0aeb0acf0ab40ade0af90aec0ac50a060be40a290b3b0b3d0b4b0b510b1f0b660b6c0b3c0b3c0b450b6a0b730b1c0b7c0b400b820b420b7b0be20a290bc60acf0af20ab30a220bd30ad10adf0afb0af80a260b0b0b110bf80a1b0b190b4f0b3a0b570b610b480b4a0b3e0b590b660b5c0ba90b790b770b910bcf0a090bdd0a090bd00abe0ab60ae30ae70acc0aea0a130b180b050bdb0a470b1e0b390b280b540b460b350b330b670b5e0b740b750b7d0bab0b6d0b710b990b0f0bc60a270b160beb0af40a020bfd0ade0aed0a170be50af00aee0a480b000b380b390b4e0b460b5e0b6f0b6d0b3e0b630b310b850b6a0b790b610b980b5c0bb80adc0a010b4c0b150bfe0adf0afe0a230bf40af40a240b0e0bfb0af10a570b270b260b4d0b730b830b530b360b5d0b420b5c0b4a0b8a0bb20b680bbc0bd70bc70afb0af90a210b2e0b030b270b120bfc0a130b130b180b2f0b3a0b320b220b520b310b5c0b610b530b630b430b400b5b0b7d0b600b650b820b9a0b860bb90bf80aeb0aff0a460b420b5b0b280b370b0f0b1e0b130b370b410b390b110b3b0b510b5e0b5a0b7c0b6f0b7d0b650b6b0b4a0b730b560bab0ba60ba10b840b7f0b500b3e0b260b300b550b4e0b590b4a0b500b290b5e0b310b6f0b370b4e0b250b770b7d0b820b690b690b990b
7f0b790b860b740b940b8d0bc40bb50b9b0bb30b6c0b320b3d0b590b430b620b480b650b5f0b270b4b0b290b600b760b0c0b400b790b9c0b8f0b850b790b8f0b990b960bb60bd50b940bcd0b0e0ca90ba80be50b380b490b710b400b3d0b6d0b690b620b330b340b750b760b420b340b250b340b830b460b5e0b860b8e0bb20bbe0b780bd80bd50bb20bac0bc70bbc0b140c950b7f0bf10a700b5b0b4f0b5a0b1e0b750b6b0b550b400b750b660b650b360b6c0b3d0b540b4b0b820b8d0b970bbb0be10be30bdc0bc70bf30bd50bd60ba40b100c6f0b340b400b3c0b2f0b4d0b370b2f0b4c0b640b510b390b660b550b660b4b0b470b470b6e0b720bad0b870bd60bc10bef0b000c180cfc0b070c080c0d0cfb0b5c0b5d0b6a0b510b350b480b5d0b3a0b710b3d0b400b6e0b690b500b430b9c0b620b520b5a0b910b530b6d0b960bf40b0c0cf80bfd0b310c020ce80b0b0c500c150b570b510b450b400b1e0b270b480b440b550b700b600b5d0b820b610b780b900b740b580b3b0b760ba00bd40be70bda0b0d0c520c470c6c0c3c0ca00ca50cf90a150beb0a490b4e0b4a0b310b890b6f0b600b1b0bad0b7a0b9c0b760bc00b9a0b880b4f0bc00b700bcc0bda0b0b0c2d0c3c0c3f0c830c860ca70ca70cd30cfb0d5861
5a5a0206de0adc0a0c0bc60a350bab0a1c0bca0a1a0b370b040b360baf0b6a0b9d0b820bd00b780b610b380b6c0b660b3d0b690b6c0b4c0b5b0b5d0b550b650b460ba20b130bd50a360b080be40a3a0bcd0ae50ae20a510b090b4e0b570ba40b7a0bab0b610b760b4e0b8b0b760b900b3d0b810b630b810b8b0b5e0b260b5c0b5d0b650bc20a0d0bee0aef0afc0a120b0d0bf30a210b080bef0a200b830b5c0b780b900b9f0b660b600b610ba60b670b740b5f0b850b4c0b680b6f0b540b980b510b5d0b080bf30ae00af20af00aed0ad30ae40a040b1e0b2f0b480b3e0b5a0b600b920b7f0baa0b620b740b3f0b680b600b880b480b6f0b660b6d0b700b940b640b5c0bd30adf0af50ae40af50ad20ae50ac00a000bf70afd0a070b640b350b620b5a0b960b760b680b400b950b460b5b0b590b770b450b570b620b870b4b0b750b6e0b060bf60ad40afd0ae70a090be80a120bc20af20a140b3e0b210b570b3f0b680b840b4f0b660b760b6e0b7b0b4b0b5c0b530b820b5c0b6d0b720b6d0b460b6c0b110bb40adc0abe0ae70aed0ad80aeb0ada0add0a090bea0a310b4b0b430b500b6d0b6e0b650b490b5e0b450b4c0b390b5d0b6a0b690b6a0b570b5c0b400b480b160bb50acd0a010bf40afe0acc0aec0ace0a0e0bc20afa0a0e0b420b2b0b700b5b0b7d0b520b870b500b650b150b790b840b750b680b7d0b680b7d0b6d0b190b020bd70a110baa0ae80aaa0ae90ab90af80aed0aea0af40a050b090b190b530b6c0b480b730b650b830b3f0b520b2c0b6b0b690b700b850ba30b760b730b3b0bf60ad60ad60ad70aeb0af50ab40af10af90a310bc50ae40ae40a3a0b3b0b1c0b4b0b730b1f0b660b6c0b5e0b3c0b570b6a0b860b1c0b690b400bd20b420b660bcc0a290bdc0acf0a190bb30aec0ad30ad10adf0ad90af80a150b0b0b220bf80a5d0b190b2d0b3a0b570b610b590b4a0b620b590b790b5c0b6f0b790b770b910bcf0a1f0bdd0a090bd00af60ab60abf0ae70a120bea0ae10a180b150bdb0a160b1e0b6a0b280b440b460b680b330b560b5e0b740b750b900bab0b940b710b9a0b100bc60aff0a160b100bf40af10afd0a010bed0af50ae50a220bee0a380b000b590b390b2c0b460b800b6f0b4a0b3e0b630b310bab0b6a0b790b610b5a0b5c0bb80adc0a010b120b150b110bdf0a100b230b170bf40a140b0e0beb0af10a150b270b570b4d0b740b830b760b360b6e0b420b910b4a0b770bb20ba20bbc0b6e0bdd0afb0a220b210b410b030b280b120b420b130b020b180b400b3a0b220b220b520b310b6d0b610b960b630b550b400b5b0b7d0b730b650b830b9a0b870bb90bf80a2b0bff0a1f0b420b5c0b280b370b0f0b410b130b270b410b290b110b3c0b510b5e0b5a0b7d0b6f0b7d0b650b490b4a0b970b560b860ba60bc70b840ba90b670b3e0b260b300b690b4e0b7e0b4a0b500b290b190b310b5e0b370b1c0b250b670b7d0b930b690b9c0b990b


Вопрос, как правильно мне эти данные собрать в нужные мне пакеты по 1544 байт начиная с 0x5a 0x5a, причем проблема в том что смещение не постоянное.

Отредактировано SeyranG (Янв. 9, 2023 20:32:55)

Офлайн

#2 Янв. 9, 2023 20:35:34

SeyranG
Зарегистрирован: 2021-12-03
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

разбор массива байт на пакеты

По сути проблема в том что я не достаточно хорошо знаю возможности Python и видимо гуглу не могу объяснить доступно что мне от него надо, потому как по моим запросам он выдает простые примеры работы с массивами. Суть вопроса заключается в следующем, как лучше в Python найти в массиве 2 байта маркирующие начало пакета, и как поделить общий входной поток на массивы по 1544 байт начиная с 2х байт начала пакета. По сути я хочу все получаемые данные вгонять в некий входной буфер, а из него уже выбирать правильные данные.

Либо еще как вариант создать стек в который одним потоком писать, а другим забирать данные. Если подскажете как это реализовать, буду премного благодарен.

Офлайн

#3 Янв. 10, 2023 00:37:47

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9716
Репутация: +  842  -
Профиль   Отправить e-mail  

разбор массива байт на пакеты


  
>>> barr = bytearray([1, 2, 3, 4, 5, 0x5a, 0x5a, 6, 7, 8, 9, 10])
>>> 
>>> barr
bytearray(b'\x01\x02\x03\x04\x05ZZ\x06\x07\x08\t\n')
>>> 
>>> bytes([0x5a, 0x5a]) in barr
True
>>> bytes([0x5a, 0x4a]) in barr
False
>>> 
>>> barr.find(bytes([0x5a, 0x5a]))
5
>>> 
>>> start_index = barr.find(bytes([0x5a, 0x5a]))
>>> barr_clean = barr[start_index:]
>>> barr_clean
bytearray(b'ZZ\x06\x07\x08\t\n')
>>> 
>>> barr_clean += bytearray([11, 12, 13, 14, 15])
>>> barr_clean
bytearray(b'ZZ\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f')
>>> 
>>> out = []
>>> block_size = 5
>>> i = 0
>>> while True:
...     i += 1
...     begin_index = (i - 1) * block_size
...     end_index = i * block_size
...     block = barr_clean[begin_index:end_index]
...     if block:
...         out.append(block)
...     else:
...         break
... 
>>> out
[bytearray(b'ZZ\x06\x07\x08'), bytearray(b'\t\n\x0b\x0c\r'), bytearray(b'\x0e\x0f')]
>>>

SeyranG
По сути проблема в том что я не достаточно хорошо знаю возможности Python
Надо и питон знать для этого, и программирование знать для этого. Потому что иначе ты как бы говоришь “мне надо нарисовать кошку, но вот я кисточку плоховато знаю и не знаю, как ей правильно мазки делать, поэтому и кошку нарисовать не могу, в этом причина”. А там надо и кисточку знать и правила рисования тоже знать надо.

SeyranG
Суть вопроса заключается в следующем, как лучше в Python найти в массиве 2 байта маркирующие начало пакета, и как поделить общий входной поток на массивы по 1544 байт начиная с 2х байт начала пакета. По сути я хочу все получаемые данные вгонять в некий входной буфер, а из него уже выбирать правильные данные.

Либо еще как вариант создать стек в который одним потоком писать, а другим забирать данные.
Ты пытаешься составить алгоритм приёма и разбора пакетов этих, а алгоритм ты составить не можешь. Питон-то за тебя алгоритм составлять не будет, питон - это как кисточка, которая не будет за тебя кошку рисовать.

SeyranG
в итоге получается что по сети я получаю не целиком пакет, а в 3 приема.
Это вот надо делать шаги в алгоритме.

Так что напиши словами алгоритм весь от начала до конца. Без какого-либо языка программирования. И вот тогда, может быть, у тебя начнёт получаться реализовывать такие составные операции.



Офлайн

#4 Янв. 10, 2023 18:54:18

SeyranG
Зарегистрирован: 2021-12-03
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

разбор массива байт на пакеты

Спасибо за помощь, вот эта строка

 barr_clean = barr[start_index:]
как оказалось в Python это называется срезы, почитал про них и все стало понятно.

py.user.next
Надо и питон знать для этого, и программирование знать для этого. Потому что иначе ты как бы говоришь “мне надо нарисовать кошку, но вот я кисточку плоховато знаю и не знаю, как ей правильно мазки делать, поэтому и кошку нарисовать не могу, в этом причина”. А там надо и кисточку знать и правила рисования тоже знать надо

Вы наверное пишите только на одном языке программирования. Я не просил алгоритм мне расписывать, просто я не понял по примерам из интернета как работать с массивами в Python, а додуматься что это срезы называется как то в голову не пришло ))

Офлайн

#5 Янв. 11, 2023 02:05:02

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9716
Репутация: +  842  -
Профиль   Отправить e-mail  

разбор массива байт на пакеты

SeyranG
Вы наверное пишите только на одном языке программирования. Я не просил алгоритм мне расписывать, просто я не понял по примерам из интернета как работать с массивами в Python, а додуматься что это срезы называется как то в голову не пришло ))
Я тебе про алгоритмы стал писать, потому что в этом гениальном коде очень много ошибок проектирования алгоритма.

Одна из ошибок - len(data) вычисляется два раза и каждый раз проверяется, не равна ли длина одному и тому же числу.

Если бы ты написал не вот так
  
            if ((i == 3) and (len(data) != 1544)):
                my_bytes = bytearray(data)
                print(my_bytes.hex())
                data = bytes([])
                t0 = time.time()
            if(len(data) == 1544):
                my_bytes = bytearray(data)
                print(my_bytes.hex())
                draw_frame(my_bytes, t0)
                data = bytes([])
                t0 = time.time()

А вот так
  
            datalen = len(data)
            packetlen = 1544
            if ((i == 3) and datalen != packetlen)):
                my_bytes = bytearray(data)
                print(my_bytes.hex())
                data = bytes([])
                t0 = time.time()
            elif(datalen == packetlen):
                my_bytes = bytearray(data)
                print(my_bytes.hex())
                draw_frame(my_bytes, t0)
                data = bytes([])
                t0 = time.time()
хотя бы, то я бы ещё в тебя поверил, что ты такой гений и тому подобное, а говнокод написал просто потому, что так надо типа.

И в таком продвинутом варианте если бы длина пакета вдруг поменялась, то, о чудо! для этого надо было бы одно число 1544 в одном месте в коде заменить на другое число и всё бы работало уже с новой длиной. Но твой умный код требует того, чтобы лазить по нему и вот это число 1544 переписывать в куче строк, чтобы случайно где-нибудь старую длину пакета не оставить. Какое везение, что этих строк тут всего две. Надо оберегать его теперь от любых изменений и дополнений, а то там и три их может стать, и десять. Чем их будет больше, тем дольше надо будет лазить по коду, чтобы где-нибудь что-нибудь случайно не забыть.

Также я подправил второй if и превратил его в elif, что ты, естественно, сразу и не заметил в таком размашистом копипастном масло масляном коде, что в итоге два действия заменило на одно действие, укрепив алгоритм по времени выполнения, так как elif даже не будет проверяться, если на первом if станет известно уже, что длина данных и длина пакета различаются.

Это всё результат чего? Это всё результат того, что ты напрямую с алгоритмами никогда не работал, поэтому ты всех этих моментов не видишь и не знаешь про них даже.

SeyranG
Вы наверное пишите только на одном языке программирования.
Ты думал, тут форум бухгалтерш, да? Там-то ты можешь сказать, какой ты гений. Прямо такой умный код написал, что ни одна бухгалтерша не разберётся, какое он безграмотное фуфло на самом деле. Я пишу не только на нескольких языках вообще, но и умею их соединять воедино ещё, поэтому у меня есть проекты и на трёх языках сразу, и на четырёх. Бывает, что я пишу программу на Shell'е, но мне надо разобрать JSON или XML быстро и надёжно, чего Shell не может, так я на Shell'е делаю вставку на питоне и там уже разбираю их, но, получив данные в этих вставках, я возвращаю эти данные в Shell и работаю с ними дальше. Это как писать на C и делать там периодически ассемблерные вставки. Принцип такой же. Если у тебя пропадает электрика в доме, то ты не садишься за учебники по электрике и не кубатуришь год или два, как там что подключать и какие уровни допуска надо иметь, а просто вызываешь нужного человека, который умеет это всё делать уже и уже где-то отучился и проучился, который твою электрику быстро чинит и уходит.



Отредактировано py.user.next (Янв. 11, 2023 02:25:35)

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version