Это первая попытка открыть исходный код базовой инфраструктуры кода, которая будет использоваться при создании 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]; ArrayListfilesInFolderCount = 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”