diff --git a/pom.xml b/pom.xml
index 91c9624..140354a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,6 +3,23 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
+
+
+ org.apache.commons
+ commons-io
+ 1.3.2
+
+
+ junit
+ junit
+ 4.12
+
+
+
+
+ 1.8
+ 1.8
+
ru.spbau.mit.kravchenkoyura
hw
diff --git a/src/main/java/ru/spbau/mit/hw4/ClientUI.java b/src/main/java/ru/spbau/mit/hw4/ClientUI.java
new file mode 100644
index 0000000..fe33298
--- /dev/null
+++ b/src/main/java/ru/spbau/mit/hw4/ClientUI.java
@@ -0,0 +1,159 @@
+package ru.spbau.mit.hw4;
+import java.awt.*;
+import java.io.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import javax.swing.*;
+import javax.swing.text.JTextComponent;
+
+public class ClientUI extends JFrame {
+ TorrentClient client;
+ Box eastBox;
+ Box centerBox;
+
+ ClientUI() {
+ super("main");
+ try {
+ client = new TorrentClient();
+ } catch (IOException e) {
+ return;
+ }
+ try {
+ client.read(new DataInputStream(new FileInputStream("client.info")));
+ } catch (IOException e) {
+ }
+
+ setBounds(100, 100, 700, 700);
+ setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+
+ eastBox = Box.createVerticalBox();
+ getContentPane().add(eastBox, BorderLayout.EAST);
+
+ centerBox = Box.createVerticalBox();
+ getContentPane().add(centerBox, BorderLayout.CENTER);
+
+ Box northBox = Box.createHorizontalBox();
+ getContentPane().add(northBox, BorderLayout.NORTH);
+
+ JButton button = new JButton("upload");
+ button.addActionListener((e) -> upload());
+ northBox.add(button);
+
+ button = new JButton("refresh list");
+ button.addActionListener((e) -> evallist());
+ northBox.add(button);
+
+ button = new JButton("exit");
+ button.addActionListener((e) -> {
+ try {
+ client.write(new DataOutputStream(new FileOutputStream("client.info", false)));
+ } catch (IOException e1) {
+ }
+ System.exit(0);
+ });
+ northBox.add(button);
+
+ evallist();
+
+ setVisible(true);
+ }
+
+ private void download(PartableFile file) {
+ System.out.print(client.files.size());
+
+ HashMap> sids = null;
+ try {
+ sids = client.getSids(file.getId());
+ } catch (IOException e) {
+ return;
+ }
+
+ JFrame frame = new JFrame("chose folder");
+ JFileChooser directoryChooser = new JFileChooser();
+ directoryChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
+ directoryChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+ frame.setVisible(true);
+ frame.add(directoryChooser);
+ if (directoryChooser.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION) {
+ try {
+ file.createFile(directoryChooser.getSelectedFile().getPath());
+ RandomAccessFile rAFile = new RandomAccessFile(file.getFile().getPath(), "rw");
+ rAFile.setLength(file.getSize());
+ }catch (FileNotFoundException e) {
+ return;
+ } catch (IOException e) {
+ return;
+ }
+ }
+ else {
+ return;
+ }
+ frame.setVisible(false);
+
+ JProgressBar pb = new JProgressBar(0, (int) Math.ceil(file.getSize() / (1.0 * TorrentClient.size)));
+ centerBox.add(new JTextField(file.toString()));
+ centerBox.add(pb);
+ centerBox.revalidate();
+
+ client.files.add(file);
+
+ ArrayList threads = new ArrayList<>();
+ for (Map.Entry> part : sids.entrySet()) {
+ Thread thread = new Thread(() -> {
+ if (client.downloadPart(part.getKey(), part.getValue(), file)) {
+ synchronized (pb) {
+ pb.setValue(pb.getValue() + 1);
+ }
+ }
+ });
+ thread.start();
+ threads.add(thread);
+ }
+ for (Thread thread : threads) {
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
+
+ private void evallist() {
+ Iterable files = null;
+ try {
+ files = client.list();
+ } catch (IOException e) {
+ return;
+ }
+ eastBox.removeAll();
+ for (PartableFile f : files) {
+ eastBox.add(new JTextField(f.toString()));
+ JButton button = new JButton("download");
+ button.addActionListener(e -> download(f));
+ eastBox.add(button);
+ }
+ eastBox.revalidate();
+ }
+
+ private void upload() {
+ JFrame frame = new JFrame("chose file");
+ JFileChooser fileChooser = new JFileChooser();
+ fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
+ frame.setVisible(true);
+ int result = fileChooser.showOpenDialog(frame);
+ frame.add(fileChooser);
+ if (result == JFileChooser.APPROVE_OPTION) {
+ try {
+ client.upload(new PartableFile(fileChooser.getSelectedFile()));
+ } catch (IOException e) {
+ }
+ System.out.println("Selected file: " + fileChooser.getSelectedFile().getAbsolutePath());
+ }
+ frame.setVisible(false);
+ }
+
+ public static void main(String[] args) throws IOException {
+ ClientUI ui = new ClientUI();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/ru/spbau/mit/hw4/PartableFile.java b/src/main/java/ru/spbau/mit/hw4/PartableFile.java
new file mode 100644
index 0000000..193f85b
--- /dev/null
+++ b/src/main/java/ru/spbau/mit/hw4/PartableFile.java
@@ -0,0 +1,92 @@
+package ru.spbau.mit.hw4;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+
+class PartableFile {
+ private int id;
+ private File file = null;
+ private String name = null;
+ private long size;
+ ArrayList parts = new ArrayList<>();
+ PartableFile(File file) {
+ this.file = file;
+ name = file.getName();
+ size = file.length();
+ for (int i = 0; i * (TorrentClient.size) < file.length(); ++i) {
+ parts.add(i);
+ }
+ }
+ PartableFile(int id, String name, long size) {
+ this.id = id;
+ this.name = name;
+ this.size = size;
+ }
+
+ PartableFile(DataInputStream in) throws IOException {
+ id = in.readInt();
+ if (in.readBoolean()) {
+ file = new File(in.readUTF());
+ name = file.getName();
+ size = file.length();
+ }
+ else {
+ name = in.readUTF();
+ size = in.readLong();
+ }
+ int count = in.readInt();
+ for (int i = 0; i < count; ++i) {
+ parts.add(in.readInt());
+ }
+ }
+
+ void write(DataOutputStream out) throws IOException {
+ out.writeInt(id);
+ if (file != null) {
+ out.writeBoolean(true);
+ out.writeUTF(file.getPath());
+ }
+ else {
+ out.writeBoolean(false);
+ out.writeUTF(name);
+ out.writeLong(size);
+ }
+ out.writeInt(parts.size());
+ for (Integer i : parts) {
+ out.writeInt(i);
+ }
+ }
+
+ void setId(int id) {
+ this.id = id;
+ }
+ String getName() {
+ return name;
+ }
+ long getSize() {
+ return size;
+ }
+ File getFile() {
+ return file;
+ }
+ void createFile(String path) throws IOException {
+ file = new File(path + "//" + name);
+ file.getParentFile().mkdirs();
+ file.createNewFile();
+ }
+ int getId() {
+ return id;
+ }
+ ArrayList getParts() {
+ return parts;
+ }
+ void addPart(int number) {
+ parts.add(number);
+ }
+ public String toString() {
+ return String.valueOf(id) + " " + getName() + " " + String.valueOf(getSize());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/ru/spbau/mit/hw4/Sid.java b/src/main/java/ru/spbau/mit/hw4/Sid.java
new file mode 100644
index 0000000..478cef8
--- /dev/null
+++ b/src/main/java/ru/spbau/mit/hw4/Sid.java
@@ -0,0 +1,23 @@
+package ru.spbau.mit.hw4;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+
+class Sid {
+ private byte[] ip;
+ private int port;
+ Sid(byte[] ip, int port) {
+ this.ip = ip;
+ this.port = port;
+ }
+ byte[] ip() {
+ return ip;
+ }
+ int getPort() {
+ return port;
+ }
+ Socket connect() throws IOException {
+ return new Socket(InetAddress.getByAddress(ip), port);
+ }
+}
diff --git a/src/main/java/ru/spbau/mit/hw4/Test.java b/src/main/java/ru/spbau/mit/hw4/Test.java
new file mode 100644
index 0000000..b026a70
--- /dev/null
+++ b/src/main/java/ru/spbau/mit/hw4/Test.java
@@ -0,0 +1,77 @@
+package ru.spbau.mit.hw4;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.junit.BeforeClass;
+
+import static org.junit.Assert.assertTrue;
+
+public class Test {
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ TorrentServer server = new TorrentServer();
+ Thread thread = new Thread(server);
+ thread.setDaemon(true);
+ thread.start();
+ }
+
+ @org.junit.Test
+ public void onePartTest() throws IOException {
+ TorrentClient client1 = new TorrentClient();
+ TorrentClient client2 = new TorrentClient();
+ File in = new File("src/main/resources/from/file1.txt");
+ File out = new File("src/main/resources/to/file1.txt");
+ int id = client1.upload(new PartableFile(in));
+ try {
+ Thread.sleep(TorrentClient.time * 2);
+ } catch (InterruptedException e) {
+ }
+ client2.download(id, "src/main/resources/to");
+ try {
+ Thread.sleep(TorrentClient.time * 2);
+ } catch (InterruptedException e) {
+ }
+ assertTrue(FileUtils.contentEquals(in, out));
+ out.delete();
+ }
+ @org.junit.Test
+ public void twoPartsTest() throws IOException {
+ TorrentClient client1 = new TorrentClient();
+ TorrentClient client2 = new TorrentClient();
+ TorrentClient client3 = new TorrentClient();
+ File in = new File("src/main/resources/from/file2.txt");
+ File middle = new File("src/main/resources/middle/file2.txt");
+ File out = new File("src/main/resources/to/file2.txt");
+ int id = client1.upload(new PartableFile(in));
+ try {
+ Thread.sleep(TorrentClient.time * 2);
+ } catch (InterruptedException e) {
+ }
+ client2.download(id, "src/main/resources/middle");
+ try {
+ Thread.sleep(TorrentClient.time * 2);
+ } catch (InterruptedException e) {
+ }
+ client1.files.get(0).parts.clear();
+ client1.files.get(0).parts.add(0);
+ client2.files.get(0).parts.clear();
+ client2.files.get(0).parts.add(1);
+ try {
+ Thread.sleep(TorrentClient.time * 2);
+ } catch (InterruptedException e) {
+ }
+ client3.download(id, "src/main/resources/to");
+ try {
+ Thread.sleep(TorrentClient.time * 2);
+ } catch (InterruptedException e) {
+ }
+ assertTrue(FileUtils.contentEquals(in, out));
+ assertTrue(FileUtils.contentEquals(in, middle));
+ assertTrue(FileUtils.contentEquals(middle, out));
+ middle.delete();
+ out.delete();
+ }
+}
diff --git a/src/main/java/ru/spbau/mit/hw4/TorrentClient.java b/src/main/java/ru/spbau/mit/hw4/TorrentClient.java
new file mode 100644
index 0000000..b7749f4
--- /dev/null
+++ b/src/main/java/ru/spbau/mit/hw4/TorrentClient.java
@@ -0,0 +1,353 @@
+package ru.spbau.mit.hw4;
+
+import java.io.*;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.*;
+
+public class TorrentClient {
+ private Sid server;
+ private ClientSid client;
+ private Socket serverConnection;
+ private DataInputStream in;
+ private DataOutputStream out;
+ ArrayList files;
+ static int time = 3000;
+ static int size = 1 << 10;
+
+ private class ClientSid implements Runnable {
+ private ServerSocket serverSocket;
+
+ @Override
+ public void run() {
+ while (true) {
+ Thread thread = null;
+ try {
+ thread = new Thread(new Handler(serverSocket.accept()));
+ thread.setDaemon(true);
+ thread.start();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ private class Handler implements Runnable{
+ DataInputStream in;
+ DataOutputStream out;
+ public Handler(Socket connection) throws IOException {
+ in = new DataInputStream(connection.getInputStream());
+ out = new DataOutputStream(connection.getOutputStream());
+ }
+
+ @Override
+ public void run() {
+ try {
+ int id;
+ switch(in.readByte()) {
+ case 1:
+ id = in.readInt();
+ for (PartableFile file : files) {
+ if (file.getId() == id) {
+ out.writeInt(file.getParts().size());
+ for (int number : file.getParts()) {
+ out.writeInt(number);
+ }
+ break;
+ }
+ }
+ break;
+ case 2:
+ id = in.readInt();
+ int part = in.readInt();
+ PartableFile file = null;
+ for(PartableFile f : files) {
+ if (f.getId() == id) {
+ file = f;
+ break;
+ }
+ }
+ RandomAccessFile f = new RandomAccessFile(file.getFile(), "rw");
+ byte[] buffer = new byte[size];
+ f.seek((size) * part);
+ int len = f.read(buffer, 0, (size));
+ out.write(buffer, 0, len);
+ break;
+ }
+ } catch (IOException e) {
+ }
+ }
+ }
+ public ClientSid() throws IOException {
+ serverSocket = new ServerSocket(0);
+ }
+ public int getPort() {
+ return serverSocket.getLocalPort();
+ }
+ }
+
+ Iterable list() throws IOException {
+ synchronized (serverConnection) {
+ ArrayList result = new ArrayList<>();
+ out.writeByte(1);
+ int count = in.readInt();
+ for (int i = 0; i < count; ++i) {
+ result.add(new PartableFile(in.readInt(), in.readUTF(), in.readLong()));
+ }
+ return result;
+ }
+ }
+
+ int upload(PartableFile f) throws IOException {
+ synchronized (serverConnection) {
+ out.writeByte(2);
+ out.writeUTF(f.getName());
+ out.writeLong(f.getSize());
+ files.add(f);
+ int id = in.readInt();
+ f.setId(id);
+ return id;
+ }
+ }
+
+ HashMap> getSids(int id) throws IOException {
+ HashMap> sids = new HashMap<>();
+ ArrayList threads = new ArrayList<>();
+ Iterable source = sources(id);
+ for (Sid sid : source) {
+ Thread thread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ Socket connection = null;
+ DataInputStream in = null;
+ DataOutputStream out = null;
+
+ try {
+ connection = sid.connect();
+ in = new DataInputStream(connection.getInputStream());
+ out = new DataOutputStream(connection.getOutputStream());
+ out.writeByte(1);
+ out.writeInt(id);
+ int n = in.readInt();
+ for (int i = 0; i < n; ++i) {
+ int cur = in.readInt();
+ synchronized (sids) {
+ if (sids.get(cur) == null) {
+ sids.put(cur, new ArrayList<>());
+ }
+ sids.get(cur).add(sid);
+ }
+ }
+ } catch (IOException e) {
+ }
+ }
+ });
+ thread.start();
+ threads.add(thread);
+ }
+ for (Thread thread : threads) {
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ }
+ }
+ return sids;
+ }
+
+ boolean downloadPart(int partNumber, ArrayList sids, PartableFile file) {
+ Socket connection = null;
+ DataInputStream in = null;
+ DataOutputStream out = null;
+ for (Sid sid : sids) {
+ try {
+ connection = sid.connect();
+ in = new DataInputStream(connection.getInputStream());
+ out = new DataOutputStream(connection.getOutputStream());
+ out.writeByte(2);
+ out.writeInt(file.getId());
+ out.writeInt(partNumber);
+ byte[] buffer = new byte[1 << 10];
+ int len = in.read(buffer);
+ RandomAccessFile rAFile = new RandomAccessFile(file.getFile().getPath(), "rw");
+ rAFile.seek((1 << 10) * partNumber);
+ rAFile.write(buffer, 0, len);
+ file.addPart(partNumber);
+ return true;
+ } catch (IOException e) {
+ }
+ }
+ return false;
+ }
+
+ void downloadFile(Map> sids, PartableFile file) {
+ ArrayList threads = new ArrayList<>();
+ for (Map.Entry> part : sids.entrySet()) {
+ Thread thread = new Thread(() -> downloadPart(part.getKey(), part.getValue(), file));
+ thread.start();
+ threads.add(thread);
+ }
+ for (Thread thread : threads) {
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
+ void download(int id, String path) throws IOException {
+ PartableFile file = null;
+ for (PartableFile f : list()) {
+ if (f.getId() == id) {
+ file = f;
+ break;
+ }
+ }
+ files.add(file);
+
+ final PartableFile finalFile = file;
+ Thread thread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ HashMap> sids = null;
+ try {
+ sids = getSids(id);
+ } catch (IOException e) {
+ return;
+ }
+ RandomAccessFile file = null;
+ try {
+ finalFile.createFile(path);
+ file = new RandomAccessFile(finalFile.getFile().getPath(), "rw");
+ file.setLength(finalFile.getSize());
+ } catch (FileNotFoundException e) {
+ } catch (IOException e) {
+ }
+ downloadFile(sids, finalFile);
+ }
+ });
+ thread.setDaemon(true);
+ thread.start();
+ }
+
+ private Iterable sources(int id) throws IOException {
+ synchronized (serverConnection) {
+ ArrayList result = new ArrayList<>();
+ out.writeByte(3);
+ out.writeInt(id);
+ int count = in.readInt();
+ for (int i = 0; i < count; ++i) {
+ byte[] ip = new byte[4];
+ for (int j = 0; j < 4; ++j) {
+ ip[j] = in.readByte();
+ }
+ result.add(new Sid(ip, in.readInt()));
+ }
+ return result;
+ }
+ }
+
+ private void setUpdate() {
+ new Timer(true).schedule(new TimerTask() {
+ @Override
+ public void run() {
+ synchronized (serverConnection) {
+ ArrayList oldFiles = new ArrayList(files);
+ try {
+ out.writeByte(4);
+ out.writeInt(client.getPort());
+ out.writeInt(oldFiles.size());
+ for (PartableFile file : oldFiles) {
+ out.writeInt(file.getId());
+ }
+ in.readBoolean();
+ } catch (IOException e) {
+ }
+ }
+ }
+ }, 0, time);
+ }
+
+ void write(DataOutputStream out) throws IOException {
+ out.writeInt(files.size());
+ for (PartableFile file : files) {
+ file.write(out);
+ }
+ }
+
+ void read(DataInputStream in) throws IOException {
+ int count = in.readInt();
+ for (int i = 0; i < count; ++i) {
+ files.add(new PartableFile(in));
+ }
+ }
+
+ TorrentClient() throws IOException {
+ serverConnection = new Socket("127.0.0.1", 8081);
+ in = new DataInputStream(serverConnection.getInputStream());
+ out = new DataOutputStream(serverConnection.getOutputStream());
+ client = new ClientSid();
+ files = new ArrayList<>();
+ Thread thread = new Thread(client);
+ thread.setDaemon(true);
+ thread.start();
+ setUpdate();
+ }
+
+ public static void main(String[] args) {
+ TorrentClient client = null;
+ try {
+ client = new TorrentClient();
+ } catch (IOException e) {
+ System.out.println("fail");
+ System.exit(0);
+ }
+ try {
+ client.read(new DataInputStream(new FileInputStream("client.info")));
+ } catch (IOException e) {
+ System.out.println("can't read file");
+ }
+ Scanner in = new Scanner(System.in);
+ while (true) {
+ String[] command = in.nextLine().split(" ");
+ if (command.length == 0) {
+ System.out.println("wrong");
+ continue;
+ }
+ try {
+ switch (command[0]) {
+ case ("list"):
+ for (PartableFile file : client.list()) {
+ System.out.println(file.toString());
+ }
+ break;
+ case ("upload"):
+ if (command.length < 2) {
+ System.out.println("wrong");
+ continue;
+ }
+ System.out.println(client.upload(new PartableFile(new File(command[1]))));
+ break;
+ case ("download"):
+ if (command.length < 3) {
+ System.out.println("wrong");
+ continue;
+ }
+ client.download(Integer.valueOf(command[1]), command[2]);
+ break;
+ case ("exit"):
+ try {
+ client.write(new DataOutputStream(new FileOutputStream("client.info", false)));
+ } catch (FileNotFoundException e) {
+ System.out.println("can't find file");
+ } catch (IOException e) {
+ System.out.println("can't write file");
+ }
+ System.exit(0);
+ default:
+ System.out.println("wrong");
+ }
+ }catch (IOException e) {
+ System.out.println("error");
+ }
+ }
+ }
+}
diff --git a/src/main/java/ru/spbau/mit/hw4/TorrentServer.java b/src/main/java/ru/spbau/mit/hw4/TorrentServer.java
new file mode 100644
index 0000000..9d7d05b
--- /dev/null
+++ b/src/main/java/ru/spbau/mit/hw4/TorrentServer.java
@@ -0,0 +1,166 @@
+package ru.spbau.mit.hw4;
+
+import java.io.*;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.*;
+
+public class TorrentServer implements Runnable{
+ private ServerSocket serverSocket;
+ private HashMap> newSids;
+ private HashMap> oldSids;
+ private ArrayList files;
+
+ @Override
+ public void run() {
+ while (true) {
+ Thread thread = null;
+ try {
+ thread = new Thread(new Handler(serverSocket.accept()));
+ thread.setDaemon(true);
+ thread.start();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ private class Handler implements Runnable{
+ DataInputStream in;
+ DataOutputStream out;
+ byte[] ip;
+ public Handler(Socket connection) throws IOException {
+ in = new DataInputStream(connection.getInputStream());
+ out = new DataOutputStream(connection.getOutputStream());
+ ip = connection.getInetAddress().getAddress();
+ }
+ @Override
+ public void run() {
+ while (true) {
+ int id;
+ try {
+ switch (in.readByte()) {
+ case 1:
+ out.writeInt(files.size());
+ for (PartableFile file : files) {
+ out.writeInt(file.getId());
+ out.writeUTF(file.getName());
+ out.writeLong(file.getSize());
+ }
+ break;
+ case 2:
+ PartableFile file = new PartableFile(files.size(), in.readUTF(), in.readLong());
+ out.writeInt(files.size());
+ files.add(file);
+ break;
+ case 3:
+ synchronized (oldSids) {
+ id = in.readInt();
+ if (oldSids.get(id) == null) {
+ out.writeInt(0);
+ break;
+ }
+ out.writeInt(oldSids.get(id).size());
+ for (Sid sid : oldSids.get(id)) {
+ for (byte b : sid.ip()) {
+ out.writeByte(b);
+ }
+ out.writeInt(sid.getPort());
+ }
+ }
+ break;
+ case 4:
+ synchronized (newSids) {
+ int port = in.readInt();
+ Sid sid = new Sid(ip, port);
+ int count = in.readInt();
+ for (int i = 0; i < count; ++i) {
+ id = in.readInt();
+ if (newSids.get(id) == null) {
+ newSids.put(id, new HashSet<>());
+ }
+ newSids.get(id).add(sid);
+ }
+ out.writeBoolean(true);
+ break;
+ }
+ }
+ } catch (IOException e) {
+ }
+ }
+ }
+ };
+
+ private void setClear() {
+ new Timer(true).schedule(new TimerTask() {
+ @Override
+ public void run() {
+ synchronized (oldSids) {
+ synchronized (newSids) {
+ oldSids = newSids;
+ newSids = new HashMap<>();
+ }
+ }
+ }
+ }, 0, TorrentClient.time * 2);
+ }
+
+ private void write(DataOutputStream out) throws IOException {
+ out.writeInt(files.size());
+ for (PartableFile file : files) {
+ file.write(out);
+ }
+ }
+
+ private void read(DataInputStream in) throws IOException {
+ int count = in.readInt();
+ for (int i = 0; i < count; ++i) {
+ files.add(new PartableFile(in));
+ }
+ }
+
+ TorrentServer() throws IOException {
+ serverSocket = new ServerSocket(8081);
+ files = new ArrayList<>();
+ newSids = new HashMap<>();
+ oldSids = new HashMap<>();
+ setClear();
+ }
+ public static void main(String[] args) {
+ TorrentServer server = null;
+ try {
+ server = new TorrentServer();
+ } catch (IOException e) {
+ System.out.println("fail");
+ System.exit(0);
+ }
+ try {
+ server.read(new DataInputStream(new FileInputStream("server.info")));
+ } catch (IOException e) {
+ System.out.println("can't read file");
+ }
+ Scanner in = new Scanner(System.in);
+ while (true) {
+ String[] command = in.nextLine().split(" ");
+ if (command.length == 0) {
+ System.out.println("wrong");
+ continue;
+ }
+ switch (command[0]) {
+ case "start":
+ new Thread(server).start();
+ break;
+ case "exit":
+ try {
+ server.write(new DataOutputStream(new FileOutputStream("server.info", false)));
+ } catch (FileNotFoundException e) {
+ System.out.println("can't find file");
+ } catch (IOException e) {
+ System.out.println("can't write file");
+ }
+ System.exit(0);
+ default:
+ System.out.println("wrong");
+ }
+ }
+ }
+}
diff --git a/src/main/resources/from/file1.txt b/src/main/resources/from/file1.txt
new file mode 100644
index 0000000..a85e37f
--- /dev/null
+++ b/src/main/resources/from/file1.txt
@@ -0,0 +1,18 @@
+ ,----------------, ,---------,
+ ,-----------------------, ," ,"|
+ ," ,"| ," ," |
+ +-----------------------+ | ," ," |
+ | .-----------------. | | +---------+ |
+ | | | | | | -==----'| |
+ | | I LOVE DOS! | | | | | |
+ | | Bad command or | | |/----|`---= | |
+ | | C:\>_ | | | ,/|==== ooo | ;
+ | | | | | // |(((( [33]| ,"
+ | `-----------------' |," .;'| |(((( | ,"
+ +-----------------------+ ;; | | |,"
+ /_)______________(_/ //' | +---------+
+ ___________________________/___ `,
+ / oooooooooooooooo .o. oooo /, \,"-----------
+ / ==ooooooooooooooo==.o. ooo= // ,`\--{)B ,"
+/_==__==========__==_ooo__ooo=_/' /___________,"
+`-----------------------------'
\ No newline at end of file
diff --git a/src/main/resources/from/file2.txt b/src/main/resources/from/file2.txt
new file mode 100644
index 0000000..e6cc8a2
--- /dev/null
+++ b/src/main/resources/from/file2.txt
@@ -0,0 +1,36 @@
+ ,----------------, ,---------,
+ ,-----------------------, ," ,"|
+ ," ,"| ," ," |
+ +-----------------------+ | ," ," |
+ | .-----------------. | | +---------+ |
+ | | | | | | -==----'| |
+ | | I LOVE DOS! | | | | | |
+ | | Bad command or | | |/----|`---= | |
+ | | C:\>_ | | | ,/|==== ooo | ;
+ | | | | | // |(((( [33]| ,"
+ | `-----------------' |," .;'| |(((( | ,"
+ +-----------------------+ ;; | | |,"
+ /_)______________(_/ //' | +---------+
+ ___________________________/___ `,
+ / oooooooooooooooo .o. oooo /, \,"-----------
+ / ==ooooooooooooooo==.o. ooo= // ,`\--{)B ,"
+/_==__==========__==_ooo__ooo=_/' /___________,"
+`-----------------------------'
+ ,----------------, ,---------,
+ ,-----------------------, ," ,"|
+ ," ,"| ," ," |
+ +-----------------------+ | ," ," |
+ | .-----------------. | | +---------+ |
+ | | | | | | -==----'| |
+ | | I LOVE DOS! | | | | | |
+ | | Bad command or | | |/----|`---= | |
+ | | C:\>_ | | | ,/|==== ooo | ;
+ | | | | | // |(((( [33]| ,"
+ | `-----------------' |," .;'| |(((( | ,"
+ +-----------------------+ ;; | | |,"
+ /_)______________(_/ //' | +---------+
+ ___________________________/___ `,
+ / oooooooooooooooo .o. oooo /, \,"-----------
+ / ==ooooooooooooooo==.o. ooo= // ,`\--{)B ,"
+/_==__==========__==_ooo__ooo=_/' /___________,"
+`-----------------------------'