Передача файлов по средствам ASN.1

Поскольку мы знаем, что любой файл состоит из массива байт, то для передачи по средствам ASN.1 нам надо знать: блок, длину блока, имя файла и можно создавать свой peer-to-peer. Мы можем ставить в очередь и передавать неограниченное число блоков данных, которые можно собирать в конкретные файлы. Хоть миллион файлов будет передаваться параллельно по блокам, как это делается в torrent клиентах.

Приводим пример, задаем произвольный файл, первый блок, длину блока данных.

Нам не важен язык написания, хоть Java, хоть C#. Абстрактный пример будет на Java.

Задаем глобальную переменную – размер блока передачи

static int blocksize = 0x3E80;

Задаем первый блок для передачи

int block = 0x01;

Задаем дескриптор файла

String filePath = «C:/Downloads/11.jpg»;

System.out.print(String.format(«block = %d \r\n», block));

System.out.print(String.format(«blocksize = %d bytes \r\n», blocksize));

Переходим к реализации функции получения блока данных

byte[] hex = GetBlock(filePath,block);

private static byte[] GetBlock(String filePath, int block) throws IOException {

//Используем произвольный доступ к файлу в режиме read

RandomAccessFile file = new RandomAccessFile(filePath, «r»);

//Получаем смещение согласно номеру блока

file.seek(GetSeek(block));

byte[] bytes = new byte[blocksize];

//Согласно смещению считываем 16 кб данных

file.read(bytes);

file.close();

return bytes;

}

//Вспомогательная функция смещения

private static long GetSeek(int block)

{

if (block == 1) {return 0;}

else {return ((block-1)*blocksize); }

}

//Самое важное еще предусмотреть, что длина файла может быть меньше 16 кб или последний блок может быть меньше 16 кб

System.out.print(String.format(«hex = %s \r\n»,GetHex(hex)));

Для контроля выводим в Hex режиме

GetHex(hex);

//Создаем stringbuilder и собираем строчку

private static String GetHex(byte[] bytes)

{

StringBuilder sb = new StringBuilder();

for (byte b : bytes) {

sb.append(String.format(«%02x», b));

}

return sb.toString();

}

Собираем произвольную TLV структуру

CreateTLV(block,filePath, hex);

private static void CreateTLV(int block, String fd, byte[] hex) {

StringBuilder TLV = new StringBuilder();

//Fd name

TLV.append(0x03);

//Fd name

TLV.append(0x03);

java.io.File file = new java.io.File(fd);

long f = file.length();

TLV.append(GetLen(f));

TLV.append(f);

//Integer block

TLV.append(0x02);

String str = Integer.toString(block);

TLV.append(GetLen(str.length()));

TLV.append(block);

//Block info

TLV.append(«03»);

TLV.append(GetLen(hex.length));

TLV.append(GetHex(hex));

//System.out.print(String.format(«TLV structure = %s \n», TLV.toString()));

System.out.print(«Bytes [] = » + TLV.toString());

}

Напишем дополнительную функцию по переводу dec в hex по определению TLV структуры

private static String GetLen(int length) {

StringBuilder str = new StringBuilder();

if (length< 0x80) str.append(Integer.toHexString(length));

if ((length> 0x80) && (length< 0x100))

{

str.append(81);

str.append(Integer.toHexString(length));

return str.toString();

}

if (length> 0x100)

{

str.append(82);

str.append(Integer.toHexString(length));

}

System.out.print(String.format(«GetLen= %s \n», str.toString()));

return str.toString();

}

Получаем результат

block = 1

blocksize = 16000 bytes

hex = ffd8ffe00010 ……..16 кб данных

Размер файла

GetLen= 8220964

Блок

GetLen= 1

Размер блока = 3e80 = 16 кб

GetLen= 823e80

3

82 2096

4433a2f446f776e6c6f6164732f31312e6a706721103823e80ffd8ffe000104a46494600010101004800480000ffe20240

2 1

1

3 82 3E80

16 кб первого блока

Тоже самое проделываем со вторым блоком и всеми остальными. По итогу передаем массив байт через сокет, раскладываем на TLV структуру и собираем файлы.