Рубрики
Без рубрики

((Как мы создали реальную SpeedForce). Создайте службу передачи файлов для беспроводной передачи данных между компьютерами в локальной сети.

Это первая попытка открыть исходный код фундаментальной инфраструктуры кода, которая будет… С пометкой “информатика”, “алгоритмы”, “бессерверный”, “java”.

Это первая попытка открыть исходный код базовой инфраструктуры кода, которая будет использоваться при создании Speed Force – Самый простой и быстрый способ отправки файлов через смартфоны, настольные компьютеры, телевизоры, умные часы, устройства Интернета вещей и Интернет.

Вы когда-нибудь задумывались, какова базовая инфраструктура передачи данных, которая обеспечивает работу таких платформ, как Google Nexus Share, Apple Airdrop и Xender? В этой статье мы собираемся углубиться в один из наиболее важных компонентов упомянутых выше сервисов. Который представляет собой передачу данных между цифровыми устройствами в локальной сети через TCP-сокеты.

TCP (Transmission Control Protocol) – это стандарт, который определяет, как устанавливать и поддерживать сетевой диалог, посредством которого прикладные программы могут обмениваться данными. TCP работает с Интернет-протоколом (IP), который определяет, как компьютеры отправляют пакеты данных друг другу. Вместе TCP и IP являются основными правилами, определяющими Интернет. – Поисковая сеть работает

Сокеты служат шлюзами для обмена данными между несколькими компьютерными системами в сети. Сетевой сокет создается с использованием комбинации IP-адреса и номера порта.

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

Примечание: В этой статье речь пойдет о программировании службы передачи файлов через TCP-сокеты с использованием языка программирования java.

Создание службы передачи файлов

1. Инициировать серверный сокет

 ServerSocket serverSocket = null;
 Socket client = null;
 try {
     serverSocket = new ServerSocket(8086);
     client = serverSocket.accept(); // Listens for a connection to be made to this socket and accepts it.
} catch (IOException e) {
     e.printStackTrace();
};

2. Инициировать клиентский сокет

Socket server = null;
try {
    server = new Socket("192.168.43.190", 8086);
} catch (IOException e) {
    e.printStackTrace();
}

3. Создайте класс протокола передачи файлов

Этот класс будет содержать функции для передачи и приема данных на обеих конечных точках сети (сокетах) соответственно. В нашей службе передачи файлов нам необходимо создать две важные функции, а именно: Функции для

  • Передача данных
  • Получать данные

Например, если клиент вызывает функцию для отправки данных в сокет сервера, сервер, с другой стороны, должен вызвать функцию для получения и сохранения данных, отправленных клиентом.

import java.io.*;
import java.net.Socket;

public class OptimizedFileTransferProtocol {
    private Socket mSocket;

    public OptimizedFileTransferProtocol(Socket socket) {
        this.mSocket = socket;
    }

    public void optimizedReceiveFile() throws IOException {

    }

    public void optimizedTransferFile(File[] fileCollection) throws IOException {


    }
}


Построение функции передачи файлов

Создайте функцию передачи файлов в четыре простых шага

1. Запишите количество файлов (видео) в поток данных сокета (socketDOS)

Внутри оптимизированной функции передачи файлов, созданной выше, запишите количество видео/файлов для передачи на socketDOS.

int temLength = fileCollection.length;
int filesCount = temLength;
for (int i = 0; i < temLength; i++) {
     if (fileCollection[i].isDirectory()) {
         filesCount += fileCollection[i].listFiles().length;
     }
}
socketDOS.writeInt(filesCount); // write the number of files sent

2. Запишите размер байта и имя каждого файла в сокет DOS

 for (int i = 0; i < fileCollection.length; i++) {
     if (fileCollection[i].isDirectory()) {
        // write the name of the directory to the socketDOS
        socketDOS.writeLong(0L);
        socketDOS.writeUTF("Directory" + fileCollection[i].getName());
        File[] filesInFolder = fileCollection[i].listFiles();
        socketDOS.writeInt(filesInFolder.length); // write the number of files in the directory to the socketDOS
        // write the name and length of all files in this directory
        for (int j = 0; j < filesInFolder.length; j++) {
             socketDOS.writeLong(filesInFolder[j].length());
             socketDOS.writeUTF(filesInFolder[j].getName());
        }
     } else {
         // not directory, write name and length of raw file
         socketDOS.writeLong(fileCollection[i].length());
         socketDOS.writeUTF(fileCollection[i].getName());
     }
}

3. Запишите байты каждого файла в сокет DOS

На этом шаге, если файл является каталогом, перейдите в файл и запишите байты каждого файла в каталоге в socketDOS, в противном случае, если файл не является каталогом, непосредственно запишите байты файла в socketDOS.

 for (int i = 0; i < fileCollection.length; i++) {
      if (fileCollection[i].isDirectory()) {
          // write the bytes of each file in the directory to the socketDOS
          File[] filesInFolder = fileCollection[i].listFiles();
          for (int j = 0; j < filesInFolder.length; j++) {
               FileInputStream fileIS = new FileInputStream(filesInFolder[j]);
               byte[] buffer = fileIS.readAllBytes();
               socketDOS.write(buffer);
               fileIS.close();
          }
     } else {
         // not directory
         FileInputStream fileIS = new FileInputStream(fileCollection[i]);
         byte[] buffer = fileIS.readAllBytes();
         socketDOS.write(buffer);
         fileIS.close(); // close file inputstream 
     }
}

4. Закройте сокет и освободите ресурсы операционной системы

Закрывая выходной поток сокета, мы также закрываем конечную точку сокета, и это все для создания функции передачи файлов внутри класса OptimizedFileTransferProtocol.

socketDOS.close();

Построение функции получения файла

Выполните следующие действия, чтобы создать функцию для получения данных при подключении клиент/сервер

1. Считывает количество файлов (видео), переданных из потока ввода данных сокета (socketDIS)

Считайте количество файлов, отправленных с другой конечной точки, поэтому мы можем использовать это количество для построения вашего цикла для считывания длины и имен для каждого отправленного файла.

// get the number of files received
int filesCount = socketDIS.readInt();

2. Считайте имя и длину каждого файла, полученного от socketdispatcher

Считайте и сохраняйте имена и длины полученных файлов из socketdispatcher

String[] filesName = new String[filesCount];
int[] filesLength = new int[filesCount];
ArrayList filesInFolderCount = new ArrayList<>();

// read out the length and name of each file received
for (int i = 0; i < filesCount; i++) {
    filesLength[i] = (int) socketDIS.readLong();
    filesName[i] = socketDIS.readUTF();
    if (filesName[i].startsWith("Directory")) {
        /**if file is a directory, read out the number (int) of files in the directory from the socketDIS**/
         filesInFolderCount.add(socketDIS.readInt());
    }
}

3. Считайте и сохраняйте байты для каждого файла, полученного от socketdispatcher

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

// read out the bytes of each file received
for (int i = 0; i < filesCount; i++) {
     String fileName = filesName[i];
     int fileLength = filesLength[i];
     if (fileName.startsWith("Directory") && fileLength == 0) {
         fileName = fileName.substring(9); // remove the string "Directory" from the folder name
         /**Since file is a directory, use the number of files in the directory to set the loop limit for reading out files from the socketDIS, that will be saved under this directory**/
          int folderFileCount = filesInFolderCount.get(0);
          filesInFolderCount.remove(0);
          int newCount = i + folderFileCount + 1;
          for (int j = i + 1; j < newCount; j++) {
               if (filesName[j].startsWith("Directory") && filesLength[j] == 0) {
                   // reached a new directory, so go back
                                break;
               }
               FileOutputStream fileOS = new FileOutputStream(saveFileInFolder(fileName, filesName[j]));
               int unreadBytes = filesLength[j];
               byte[] buffer;
               try {
                    buffer = new byte[filesLength[j]];
               } catch (OutOfMemoryError outOfMemoryError) {
                    buffer = new byte[1_000_000];
               }
               while (unreadBytes > 0) {
                      int readBytes = socketDIS.read(buffer, 0, Math.min(unreadBytes, buffer.length));
                      if (readBytes == -1) { 
                          break; //End of file reached
                      }
                      fileOS.write(buffer, 0, readBytes);
                      unreadBytes -= readBytes;
                }
                fileOS.close();
                // move i to the next index of the filesCount
                i = j;
          }
       } else {
           // not directory, save file in base directory
           FileOutputStream fileOS = new FileOutputStream(createFile(fileName));
           int unreadBytes = fileLength;
           byte[] buffer;
           try {
                buffer = new byte[fileLength];
           } catch (OutOfMemoryError outOfMemoryError) {
                buffer = new byte[1_000_000];
           }
           while (unreadBytes > 0) {
                 int readBytes = socketDIS.read(buffer, 0, Math.min(unreadBytes, buffer.length));
                 if (readBytes == -1) {
                    //End of file reached
                    break;
                 }
                 fileOS.write(buffer, 0, readBytes);
                 unreadBytes -= readBytes;
           }
           fileOS.close();
       }
}

И это все!!! упс

Вывод

Используя приведенные выше иллюстрации кода, я надеюсь, что теперь у вас есть представление о том, как строятся системы беспроводной передачи данных по локальной сети. Для полной реализации программы локальной сети для беспроводной передачи/приема мультимедийных элементов (изображений, видео, файлов и т.д.) На/с другого компьютера, подключенного к локальной сети, с использованием протокола управления передачей (TCP) Сокеты ознакомьтесь с этим репозиторием Github экверике .

Оригинал: “https://dev.to/pekwerike/how-we-built-a-real-life-speedforce-build-a-file-transfer-service-for-wireless-data-transfer-among-computers-in-a-lan-53c0”