Поскольку мы знаем, что любой файл состоит из массива байт, то для передачи по средствам 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 структуру и собираем файлы.