├── scripts ├── createpeerfiles.sh ├── createfiles.sh └── createsizefiles.sh ├── config.json ├── .classpath ├── src ├── bench │ ├── local │ │ ├── Evaluate.java │ │ ├── Throughput.java │ │ └── Launch.java │ └── remote │ │ └── Launch.java ├── node │ ├── client │ │ ├── Connection.java │ │ └── Client.java │ ├── server │ │ ├── Server.java │ │ └── OpenServer.java │ └── Peer.java ├── util │ ├── PeerQueue.java │ ├── DistributedHashtable.java │ └── Util.java └── index │ └── server │ ├── Assign.java │ ├── Deploy.java │ ├── Task.java │ └── IndexingServer.java ├── .project ├── .gitignore └── README.md /scripts/createpeerfiles.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | i=$1 4 | NUMFILES=$2 5 | 6 | mkdir peer$i 7 | for (( j=0; j<$NUMFILES; j++ )); do 8 | base64 /dev/urandom | head -c $((RANDOM%20000+1000)) > peer$i/file-p$i-0$j 9 | done 10 | -------------------------------------------------------------------------------- /scripts/createfiles.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | NUMPEERS=$1 4 | NUMFILES=$2 5 | 6 | for (( i=0; i<$NUMPEERS; i++ )); do 7 | mkdir peer$i 8 | for ((j=0; j<$NUMFILES; j++)); do 9 | base64 /dev/urandom | head -c $((RANDOM%20000+1000)) > peer$i/file-p$i-0$j 10 | done 11 | done 12 | -------------------------------------------------------------------------------- /scripts/createsizefiles.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | NUMPEERS=$1 4 | NUMFILES=$2 5 | FILESIZE=$3 6 | 7 | for (( i=0; i<$NUMPEERS; i++ )); do 8 | mkdir peer$i 9 | for ((j=0; j<$NUMFILES; j++)); do 10 | base64 /dev/urandom | head -c $FILESIZE > peer$i/file-p$i-0$j 11 | done 12 | done 13 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "peers":[ 3 | "localhost:13000:peer0", 4 | "localhost:13001:peer1" 5 | ], 6 | "servers":[ 7 | "localhost:15000", 8 | "localhost:15001", 9 | "localhost:15002", 10 | "localhost:15003", 11 | "localhost:15004", 12 | "localhost:15005", 13 | "localhost:15006", 14 | "localhost:15007" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/bench/local/Evaluate.java: -------------------------------------------------------------------------------- 1 | package bench.local; 2 | 3 | import node.client.Client; 4 | 5 | public class Evaluate extends Thread { 6 | private Client client; 7 | private int operations; 8 | 9 | public Evaluate(Client client, int operations) { 10 | this.client = client; 11 | this.operations = operations; 12 | } 13 | 14 | public void run() { 15 | 16 | client.bench(operations); 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | decentralize-p2p-file-sharing 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/node/client/Connection.java: -------------------------------------------------------------------------------- 1 | package node.client; 2 | 3 | import java.net.Socket; 4 | 5 | public class Connection { 6 | 7 | private Socket socket; 8 | private String directory; 9 | 10 | public Connection(Socket socket, String directory){ 11 | this.socket = socket; 12 | this.directory = directory; 13 | } 14 | 15 | public Socket getSocket(){ 16 | return socket; 17 | } 18 | 19 | public String getDirectory(){ 20 | return directory; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | *.pydevproject 3 | .metadata 4 | .gradle 5 | bin/ 6 | tmp/ 7 | *.tmp 8 | *.bak 9 | *.swp 10 | *~.nib 11 | local.properties 12 | .settings/ 13 | .loadpath 14 | 15 | # External tool builders 16 | .externalToolBuilders/ 17 | 18 | # Locally stored "Eclipse launch configurations" 19 | *.launch 20 | 21 | # CDT-specific 22 | .cproject 23 | 24 | # PDT-specific 25 | .buildpath 26 | 27 | # sbteclipse plugin 28 | .target 29 | 30 | # TeXlipse plugin 31 | .texlipse 32 | 33 | .DS_Store 34 | 35 | *.jar 36 | 37 | # Test files 38 | peer*/ 39 | downloads-*/ 40 | replication-*/ 41 | -------------------------------------------------------------------------------- /src/util/PeerQueue.java: -------------------------------------------------------------------------------- 1 | package util; 2 | 3 | import java.io.Serializable; 4 | import java.util.LinkedList; 5 | 6 | @SuppressWarnings("serial") 7 | public class PeerQueue implements Serializable{ 8 | 9 | private LinkedList queue; 10 | 11 | public T peek() { 12 | return queue.peek(); 13 | } 14 | 15 | public T poll() { 16 | return queue.poll(); 17 | } 18 | 19 | public void add(T t) { 20 | queue.add(t); 21 | 22 | } 23 | 24 | public PeerQueue() { 25 | queue = new LinkedList(); 26 | } 27 | 28 | public int Size() { 29 | return queue.size(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/index/server/Assign.java: -------------------------------------------------------------------------------- 1 | package index.server; 2 | 3 | import java.net.Socket; 4 | 5 | public class Assign extends Thread { 6 | 7 | private IndexingServer indexingServer; 8 | 9 | public Assign(IndexingServer indexingServer) { 10 | this.indexingServer = indexingServer; 11 | } 12 | 13 | public void run() { 14 | 15 | while (true) { 16 | if (indexingServer.peekPeerQueue() == null) { 17 | try { 18 | Thread.sleep(1); 19 | } catch (InterruptedException e) { 20 | e.printStackTrace(); 21 | } 22 | continue; 23 | } 24 | synchronized (indexingServer.getPeerQueue()) { 25 | Socket socket = indexingServer.pollPeerQueue(); 26 | Task t = new Task(socket, indexingServer); 27 | t.start(); 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/bench/local/Throughput.java: -------------------------------------------------------------------------------- 1 | package bench.local; 2 | 3 | import node.client.Client; 4 | 5 | public class Throughput extends Thread { 6 | private Client client; 7 | private int operations; 8 | 9 | public Throughput(Client client, int operations) { 10 | this.client = client; 11 | this.operations = operations; 12 | } 13 | 14 | public void run() { 15 | 16 | 17 | try { 18 | long bytes; 19 | client.registry(false); 20 | System.out.println("Registered!"); 21 | 22 | long start = System.currentTimeMillis(); 23 | 24 | bytes = client.bench_download(operations); 25 | 26 | long time = (System.currentTimeMillis() - start); 27 | 28 | System.out.println("Time for doing " + operations 29 | + " downloads in peer " + client.getPeer().getPeerId() + " was " 30 | + time + " ms."); 31 | 32 | System.out.println("Thoughput of peer " + + client.getPeer().getPeerId() + " = " + bytes/(time/1000) + " bytes/s."); 33 | 34 | } catch (Exception e) { 35 | e.printStackTrace(); 36 | } 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/index/server/Deploy.java: -------------------------------------------------------------------------------- 1 | package index.server; 2 | 3 | import java.io.IOException; 4 | import java.net.ServerSocket; 5 | import java.util.ArrayList; 6 | 7 | import util.DistributedHashtable; 8 | 9 | public class Deploy { 10 | 11 | public static ArrayList serverList; 12 | public static int numPeers; 13 | 14 | public static void main(String[] args) throws IOException { 15 | // Creating servers 16 | 17 | if (args.length < 1) { 18 | System.out.println("Usage: java -jar build/Deploy.jar "); 19 | return; 20 | } 21 | 22 | int id = Integer.parseInt(args[0]); 23 | 24 | serverList = DistributedHashtable.readConfigFile("servers"); 25 | 26 | String[] peerAddress; 27 | int port; 28 | 29 | peerAddress = serverList.get(id).split(":"); 30 | port = Integer.parseInt(peerAddress[1]); 31 | 32 | ServerSocket serverSocket = new ServerSocket(port); 33 | 34 | // start server 35 | IndexingServer server = new IndexingServer(serverSocket); 36 | server.start(); 37 | 38 | // start assign server 39 | Assign assign = new Assign(server); 40 | assign.start(); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/node/server/Server.java: -------------------------------------------------------------------------------- 1 | package node.server; 2 | 3 | import java.io.DataInputStream; 4 | import java.io.DataOutputStream; 5 | import java.io.File; 6 | import java.io.FileInputStream; 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.net.Socket; 10 | 11 | import util.Util; 12 | 13 | public class Server extends Thread { 14 | 15 | private String directory; 16 | private Socket socket; 17 | 18 | public Server(Socket socket, String directory) { 19 | this.directory = directory; 20 | this.socket = socket; 21 | } 22 | 23 | public void run() { 24 | try { 25 | //System.out.println("here"); 26 | DataInputStream dIn = new DataInputStream(socket.getInputStream()); 27 | String fileName = dIn.readUTF(); 28 | //System.out.println("fileName read " + fileName); 29 | InputStream in = new FileInputStream(directory + "/" + fileName); 30 | long fileSize = new File(directory + "/" + fileName).length(); 31 | DataOutputStream dOut = new DataOutputStream(socket.getOutputStream()); 32 | dOut.writeLong(fileSize); 33 | dOut.flush(); 34 | //System.out.println("fileSize writen"); 35 | 36 | Util.copy(in, dOut, fileSize); 37 | in.close(); 38 | } catch (IOException ioe) { 39 | ioe.printStackTrace(); 40 | } 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/util/DistributedHashtable.java: -------------------------------------------------------------------------------- 1 | package util; 2 | 3 | import java.io.FileReader; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Iterator; 7 | 8 | import org.json.simple.JSONArray; 9 | import org.json.simple.JSONObject; 10 | import org.json.simple.parser.JSONParser; 11 | 12 | public class DistributedHashtable { 13 | 14 | public static ArrayList readConfigFile(String element) 15 | throws IOException { 16 | // read from a JSON 17 | JSONParser parser = new JSONParser(); 18 | ArrayList peerList = new ArrayList(); 19 | 20 | try { 21 | 22 | Object obj = parser.parse(new FileReader("config.json")); 23 | 24 | JSONObject jsonObject = (JSONObject) obj; 25 | 26 | // loop array 27 | JSONArray msg = (JSONArray) jsonObject.get(element); 28 | Iterator iterator = msg.iterator(); 29 | 30 | while (iterator.hasNext()) { 31 | peerList.add((String) iterator.next()); 32 | } 33 | 34 | } catch (Exception e) { 35 | System.out.println("Couldn't read from config file"); 36 | e.printStackTrace(); 37 | return null; 38 | } 39 | 40 | return peerList; 41 | } 42 | 43 | public static int hash(String key, int numPeers) { 44 | int sum = 0; 45 | for (int i = 0; i < key.length(); i++) 46 | sum += key.charAt(i); 47 | //System.out.println("filename: " + key + " " + sum + " " + sum % numPeers); 48 | return sum % numPeers; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/util/Util.java: -------------------------------------------------------------------------------- 1 | package util; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.File; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.io.InputStreamReader; 8 | import java.io.OutputStream; 9 | import java.net.URL; 10 | import java.util.ArrayList; 11 | 12 | public class Util { 13 | 14 | public static ArrayList listFilesForFolder(final File folder) { 15 | 16 | ArrayList fileNames = new ArrayList(); 17 | 18 | for (final File fileEntry : folder.listFiles()) 19 | fileNames.add(fileEntry.getName()); 20 | 21 | return fileNames; 22 | 23 | } 24 | 25 | public static void copy(InputStream in, OutputStream out, long fileSize) 26 | throws IOException { 27 | //System.out.println("fileSize = " + fileSize); 28 | byte[] buffer = new byte[1024]; 29 | int count = 0, total = 0; 30 | //long start = System.currentTimeMillis(); 31 | while (total != fileSize) { 32 | count = in.read(buffer); 33 | //System.out.println("count = " + count); 34 | out.write(buffer, 0, count); 35 | total += count; 36 | } 37 | out.flush(); 38 | //System.out.println("Download took " + (System.currentTimeMillis() - start) + " ms."); 39 | } 40 | 41 | public static long toSeconds(long start, long end) { 42 | return (end - start) / 1000; 43 | } 44 | 45 | public static String getExternalIP() throws IOException { 46 | URL url = new URL("http://checkip.amazonaws.com/"); 47 | BufferedReader br = new BufferedReader(new InputStreamReader( 48 | url.openStream())); 49 | return br.readLine(); 50 | } 51 | 52 | public static double calculateAverage(ArrayList times) { 53 | Long sum = 0L; 54 | if (!times.isEmpty()) { 55 | for (Long time : times) { 56 | sum += time; 57 | } 58 | return sum.doubleValue() / times.size(); 59 | } 60 | return sum; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/index/server/Task.java: -------------------------------------------------------------------------------- 1 | package index.server; 2 | 3 | 4 | import java.io.DataInputStream; 5 | import java.io.DataOutputStream; 6 | import java.io.ObjectOutputStream; 7 | import java.net.Socket; 8 | import java.util.ArrayList; 9 | 10 | import node.Peer; 11 | 12 | public class Task extends Thread { 13 | 14 | private Socket socket; 15 | private IndexingServer indexingServer; 16 | 17 | public Task(Socket socket, IndexingServer indexingServer) { 18 | this.socket = socket; 19 | this.indexingServer = indexingServer; 20 | } 21 | 22 | public void run() { 23 | 24 | try { 25 | 26 | while (true) { 27 | DataInputStream dIn = new DataInputStream( 28 | socket.getInputStream()); 29 | DataOutputStream dOut = null; 30 | 31 | byte option = dIn.readByte(); 32 | // System.out.println(option); 33 | String fileName, peer; 34 | ArrayList peerList; 35 | 36 | switch (option) { 37 | case 0: 38 | // registry 39 | fileName = dIn.readUTF(); 40 | peer = dIn.readUTF(); 41 | dOut = new DataOutputStream(socket.getOutputStream()); 42 | dOut.writeBoolean(indexingServer.registry(fileName, peer)); 43 | dOut.flush(); 44 | break; 45 | case 1: 46 | // lookup 47 | fileName = dIn.readUTF(); 48 | peerList = indexingServer.lookup(fileName); 49 | //dOut = new DataOutputStream(socket.getOutputStream()); 50 | ObjectOutputStream oout = new ObjectOutputStream(socket.getOutputStream()); 51 | /*dOut.writeInt(peerList.size()); 52 | dOut.flush(); 53 | if (peerList.size() != 0) { 54 | for (Peer p : peerList) 55 | dOut.writeUTF(p.toString()); 56 | dOut.flush(); 57 | }*/ 58 | oout.writeObject(peerList); 59 | oout.flush(); 60 | break; 61 | } 62 | } 63 | } catch (Exception e) { 64 | //System.out.println("Nothing happened"); 65 | // e.printStackTrace(); 66 | 67 | } 68 | 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/index/server/IndexingServer.java: -------------------------------------------------------------------------------- 1 | package index.server; 2 | 3 | import java.io.IOException; 4 | import java.net.ServerSocket; 5 | import java.net.Socket; 6 | import java.util.ArrayList; 7 | import java.util.Hashtable; 8 | 9 | import util.PeerQueue; 10 | import node.Peer; 11 | 12 | public class IndexingServer extends Thread { 13 | 14 | private ServerSocket serverSocket; 15 | 16 | private Hashtable> index; 17 | 18 | private PeerQueue peerQueue; 19 | 20 | public IndexingServer(ServerSocket serverSocket) { 21 | this.serverSocket = serverSocket; 22 | 23 | index = new Hashtable>(); 24 | 25 | peerQueue = new PeerQueue(); 26 | } 27 | 28 | // setters 29 | public void setPeerQueue(PeerQueue peerQueue) { 30 | this.peerQueue = peerQueue; 31 | } 32 | 33 | // getters 34 | public PeerQueue getPeerQueue() { 35 | return peerQueue; 36 | } 37 | 38 | // Queue methods 39 | public void addToPeerQueue(Socket sock) { 40 | peerQueue.add(sock); 41 | } 42 | 43 | public Socket peekPeerQueue() { 44 | return peerQueue.peek(); 45 | } 46 | 47 | public Socket pollPeerQueue() { 48 | return peerQueue.poll(); 49 | } 50 | 51 | public boolean registry(String fileName, String peer) throws Exception { 52 | //System.out.println(fileName + " " + peer + " at server " + serverSocket.getLocalPort()); 53 | String[] peerItems = peer.split(":"); 54 | 55 | Peer p = new Peer(Integer.parseInt(peerItems[0]), peerItems[1], 56 | Integer.parseInt(peerItems[2]), peerItems[3]); 57 | try { 58 | if (index.containsKey(fileName)) { 59 | //index.get(fileName).add(p); 60 | if(index.get(fileName).contains(p)) 61 | return true; 62 | index.get(fileName).add(p); 63 | return true; 64 | } else { 65 | index.put(fileName, new ArrayList()); 66 | index.get(fileName).add(p); 67 | return true; 68 | } 69 | } catch (Exception e) { 70 | return false; 71 | } 72 | } 73 | 74 | public ArrayList lookup(String fileName) { 75 | if (index.containsKey(fileName)) { 76 | return index.get(fileName); 77 | } 78 | return new ArrayList(); 79 | } 80 | 81 | public void run() { 82 | 83 | System.out.println("\nRunning server at port " + serverSocket.getLocalPort() + "\n"); 84 | 85 | while (true) { 86 | Socket socket = null; 87 | try { 88 | socket = serverSocket.accept(); 89 | } catch (IOException e) { 90 | e.printStackTrace(); 91 | } 92 | synchronized (getPeerQueue()) { 93 | addToPeerQueue(socket); 94 | } 95 | /* 96 | * try { Thread.sleep(2); } catch (InterruptedException e) { 97 | * e.printStackTrace(); } 98 | */ 99 | } 100 | 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/node/server/OpenServer.java: -------------------------------------------------------------------------------- 1 | package node.server; 2 | 3 | import java.io.DataInputStream; 4 | import java.io.DataOutputStream; 5 | import java.io.File; 6 | import java.io.FileInputStream; 7 | import java.io.FileOutputStream; 8 | import java.io.InputStream; 9 | import java.io.OutputStream; 10 | import java.net.Socket; 11 | 12 | import util.Util; 13 | 14 | public class OpenServer extends Thread { 15 | 16 | private String directory; 17 | private Socket socket; 18 | 19 | public OpenServer(Socket socket, String directory) { 20 | this.directory = directory; 21 | this.socket = socket; 22 | } 23 | 24 | public void run() { 25 | try { 26 | while (true) { 27 | String fileName; 28 | long fileSize; 29 | DataInputStream dIn = new DataInputStream( 30 | socket.getInputStream()); 31 | DataOutputStream dOut = null; 32 | 33 | byte option = dIn.readByte(); 34 | switch (option) { 35 | case 0: 36 | // download 37 | 38 | fileName = dIn.readUTF(); 39 | //System.out.println("fileName read " + fileName); 40 | File file = new File(directory + "/"+ fileName); 41 | InputStream in = new FileInputStream(file); 42 | fileSize = file.length(); 43 | //System.out.println("trying"); 44 | dOut = new DataOutputStream(socket.getOutputStream()); 45 | //System.out.println("writing"); 46 | dOut.writeLong(fileSize); 47 | dOut.flush(); 48 | //System.out.println("fileSize writen"); 49 | 50 | Util.copy(in, dOut, fileSize); 51 | in.close(); 52 | 53 | break; 54 | case 1: 55 | // replicating files 56 | //System.out.println("here"); 57 | int peerId = dIn.readInt(); 58 | fileName = dIn.readUTF(); 59 | //System.out.println("fileName read " + fileName); 60 | fileSize = dIn.readLong(); 61 | //System.out.println("fileSize read = " + fileSize); 62 | String folder = "replication-peer" + peerId + "/"; 63 | File f = new File(folder); 64 | Boolean created = false; 65 | if (!f.exists()) { 66 | try { 67 | created = f.mkdir(); 68 | } catch (Exception e) { 69 | System.out 70 | .println("Couldn't create the folder, the file will be saved in the current directory!"); 71 | } 72 | } else { 73 | created = true; 74 | } 75 | 76 | OutputStream out = (created) ? new FileOutputStream( 77 | f.toString() + "/" + fileName) 78 | : new FileOutputStream(fileName); 79 | Util.copy(dIn, out, fileSize); 80 | out.close(); 81 | //System.out.println("File " + fileName + " received from peer " + peerId); 82 | dOut = new DataOutputStream(socket.getOutputStream()); 83 | dOut.writeUTF("File recieved"); 84 | break; 85 | default: 86 | throw new Exception(); 87 | } 88 | } 89 | } catch (Exception e) { 90 | //e.printStackTrace(); 91 | } 92 | 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/bench/remote/Launch.java: -------------------------------------------------------------------------------- 1 | package bench.remote; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.net.Socket; 6 | import java.util.ArrayList; 7 | 8 | import util.DistributedHashtable; 9 | import util.Util; 10 | import node.Peer; 11 | import node.client.Client; 12 | 13 | public class Launch { 14 | 15 | public static ArrayList peerList; 16 | public static ArrayList serverList; 17 | 18 | public static void main(String[] args) { 19 | 20 | if (args.length < 2) { 21 | System.out 22 | .println("Usage: java -jar build/RemoteBench.jar "); 23 | return; 24 | } 25 | 26 | int id = Integer.parseInt(args[0]); 27 | if (id < 0 && id > peerList.size()) { 28 | System.out 29 | .println("Id should be positive and smaller than the number of peers allowed!"); 30 | return; 31 | } 32 | 33 | int operations = Integer.parseInt(args[1]); 34 | if (operations < 0) { 35 | System.out 36 | .println("Number of operations should be a positive number!"); 37 | return; 38 | } 39 | 40 | try { 41 | peerList = DistributedHashtable.readConfigFile("peers"); 42 | serverList = DistributedHashtable.readConfigFile("servers"); 43 | } catch (IOException e) { 44 | e.printStackTrace(); 45 | } 46 | 47 | String[] serverAddress, peerAddress; 48 | 49 | peerAddress = peerList.get(id).split(":"); 50 | String address = peerAddress[0]; 51 | int port = Integer.parseInt(peerAddress[1]); 52 | 53 | String dir = peerAddress[2]; 54 | File folder = new File(dir); 55 | 56 | if (!folder.isDirectory()) { 57 | System.out.println("Put a valid directory name"); 58 | return; 59 | } 60 | 61 | ArrayList fileNames = Util.listFilesForFolder(folder); 62 | Peer peer = null; 63 | try { 64 | peer = new Peer(id, address, port, dir, fileNames, 65 | fileNames.size()); 66 | } catch (IOException e) { 67 | e.printStackTrace(); 68 | } 69 | 70 | Client c = new Client(peer); 71 | c.startOpenServer(); 72 | 73 | ArrayList serverSocketList = new ArrayList(); 74 | 75 | for (int i = 0; i < serverList.size(); i++) { 76 | serverAddress = serverList.get(i).split(":"); 77 | address = serverAddress[0]; 78 | port = Integer.parseInt(serverAddress[1]); 79 | 80 | try { 81 | System.out.println("Testing connection to server " 82 | + address + ":" + port); 83 | Socket s = new Socket(address, port); 84 | serverSocketList.add(s); 85 | System.out.println("Server " + address + ":" + port 86 | + " is running."); 87 | } catch (Exception e) { 88 | i--; 89 | port--; 90 | } 91 | } 92 | c.setServerSocketList(serverSocketList); 93 | 94 | c.setPeerSocketList(new Socket[peerList.size()]); 95 | 96 | c.bench(operations); 97 | 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Decentralized P2P File Sharing System 2 | 3 | ## Compilation 4 | This project is a simple implementation of a Decentralized P2P File Sharing System 5 | with a Distributed Hashtable, using Java and Sockets. 6 | 7 | To compile the project, you need [Apache Ant](http://ant.apache.org/) and a [JSON lib](https://code.google.com/p/json-simple/) under a ```lib``` folder. You need to create an empty ```bin``` folder too. 8 | And then just: 9 | 10 | ```sh 11 | $ ant clean & ant compile & ant jar 12 | ``` 13 | 14 | ## Configuration 15 | All the configuration of peers and and server is done in the [config.json](https://github.com/gmendonca/decentralize-p2p-file-sharing/blob/master/config.json) file. 16 | This is a example how the file look like with 8 servers and 8 peers. In the provided example 17 | it's using a single machine with different ports and folders, but it's possible to use ip address here too. 18 | 19 | ```json 20 | { 21 | "peers":[ 22 | "localhost:13000:peer0", 23 | "localhost:13001:peer1", 24 | "localhost:13002:peer2", 25 | "localhost:13003:peer3", 26 | "localhost:13004:peer4", 27 | "localhost:13005:peer5", 28 | "localhost:13006:peer6", 29 | "localhost:13007:peer7" 30 | ], 31 | "servers":[ 32 | "localhost:15000", 33 | "localhost:15001", 34 | "localhost:15002", 35 | "localhost:15003", 36 | "localhost:15004", 37 | "localhost:15005", 38 | "localhost:15006", 39 | "localhost:15007" 40 | ] 41 | } 42 | ``` 43 | 44 | ## Running 45 | To start a server, you need to run: 46 | 47 | ```sh 48 | $ java -jar build/Deploy.jar 49 | ``` 50 | 51 | The `````` will reflect the order specified in the config file. For example, 52 | Server 0 will be "localhost:15000" in the example above. 53 | 54 | A client could be started using: 55 | 56 | ```sh 57 | $ java -jar build/Client.jar 58 | ``` 59 | 60 | This assumes that you have a ```peer``` folder with files. 61 | There are some helpers scripts to automate the creation of folders 62 | and files for testbeds on the folder [scripts](https://github.com/gmendonca/decentralize-p2p-file-sharing/tree/master/scripts). 63 | Again, it reflects the order of the config file. 64 | 65 | ## Benchmark 66 | 67 | There are two types of Benchmarking available on this project, a remote and a local one. 68 | 69 | For running the local benchmarking, you need to run the following command: 70 | 71 | ```sh 72 | $ java -jar build/LocalBench.jar 73 | ``` 74 | 75 | In this case, you don't need to run the server or the client separated, 76 | it will create everything based on the config file. 77 | However, you still need to provide the folder and files. 78 | The files should be in the format ```file-p-0```, the script [createfiles.sh](https://github.com/gmendonca/decentralize-p2p-file-sharing/tree/master/scripts/createfiles.sh) create files using the this pattern. You can select the number of peers and files per peer and run it like that: 79 | 80 | ```sh 81 | $ bash scripts/configfiles.sh 82 | ``` 83 | 84 | 85 | The is two different approaches for the Benchmarking, The ```0``` option is the normal 86 | one that will benchmark registry, search and obtain files. The second one ```1``` it will benchmark just the download. 87 | 88 | 89 | The remote benchmarking will do the same things as the local benchmark but it should run individually in each node. 90 | For this, it's necessary to run the Server First and then the Remote Bench. To this to work, the server must be running in each node specified on the config file and each node has to have a copy of the config file. 91 | 92 | ```sh 93 | $ java -jar build/Deploy.jar & 94 | $ java -jar build/RemoteBench.jar 95 | ``` 96 | 97 | For all the options you can specify how many operations of Registry, Search and Obtain files it will run. 98 | -------------------------------------------------------------------------------- /src/bench/local/Launch.java: -------------------------------------------------------------------------------- 1 | package bench.local; 2 | 3 | import index.server.Assign; 4 | import index.server.IndexingServer; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.net.ServerSocket; 9 | import java.net.Socket; 10 | import java.util.ArrayList; 11 | 12 | import node.Peer; 13 | import node.client.Client; 14 | import util.DistributedHashtable; 15 | import util.Util; 16 | 17 | public class Launch { 18 | 19 | public static ArrayList peerList; 20 | public static ArrayList serverList; 21 | 22 | public static void main(String[] args) throws Exception { 23 | 24 | if (args.length < 2) { 25 | System.out 26 | .println("Usage: java -jar build/LocalBench.jar "); 27 | return; 28 | } 29 | 30 | int bench = Integer.parseInt(args[0]); 31 | if (bench != 0 && bench != 1) { 32 | System.out 33 | .println("Bench Option should be 0 for benchmarking all the three operations or 1 for just thoughput"); 34 | return; 35 | } 36 | 37 | int operations = Integer.parseInt(args[1]); 38 | if (operations < 0) { 39 | System.out 40 | .println("Number of operations should be a positive number!"); 41 | return; 42 | } 43 | 44 | try { 45 | peerList = DistributedHashtable.readConfigFile("peers"); 46 | serverList = DistributedHashtable.readConfigFile("servers"); 47 | } catch (IOException e) { 48 | e.printStackTrace(); 49 | } 50 | 51 | String[] serverAddress, peerAddress; 52 | int port; 53 | for (String server : serverList) { 54 | serverAddress = server.split(":"); 55 | port = Integer.parseInt(serverAddress[1]); 56 | 57 | ServerSocket serverSocket = null; 58 | try { 59 | serverSocket = new ServerSocket(port); 60 | } catch (IOException e) { 61 | e.printStackTrace(); 62 | } 63 | 64 | // start server 65 | IndexingServer indexserver = new IndexingServer(serverSocket); 66 | indexserver.start(); 67 | 68 | // start assign server 69 | Assign assign = new Assign(indexserver); 70 | assign.start(); 71 | } 72 | 73 | ArrayList clients = new ArrayList(); 74 | 75 | for (int id = 0; id < peerList.size(); id++) { 76 | peerAddress = peerList.get(id).split(":"); 77 | String address = peerAddress[0]; 78 | port = Integer.parseInt(peerAddress[1]); 79 | 80 | String dir = peerAddress[2]; 81 | File folder = new File(dir); 82 | 83 | if (!folder.isDirectory()) { 84 | System.out.println("Put a valid directory name"); 85 | return; 86 | } 87 | 88 | ArrayList fileNames = Util.listFilesForFolder(folder); 89 | Peer peer = null; 90 | try { 91 | peer = new Peer(id, address, port, dir, fileNames, 92 | fileNames.size()); 93 | } catch (IOException e) { 94 | e.printStackTrace(); 95 | } 96 | 97 | Client c = new Client(peer); 98 | c.startOpenServer(); 99 | 100 | ArrayList serverSocketList = new ArrayList(); 101 | 102 | for (int i = 0; i < serverList.size(); i++) { 103 | serverAddress = serverList.get(i).split(":"); 104 | address = serverAddress[0]; 105 | port = Integer.parseInt(serverAddress[1]); 106 | 107 | try { 108 | System.out.println("Testing connection to server " 109 | + address + ":" + port); 110 | Socket s = new Socket(address, port); 111 | serverSocketList.add(s); 112 | System.out.println("Server " + address + ":" + port 113 | + " is running."); 114 | } catch (Exception e) { 115 | i--; 116 | port--; 117 | } 118 | } 119 | c.setServerSocketList(serverSocketList); 120 | 121 | c.setPeerSocketList(new Socket[peerList.size()]); 122 | clients.add(c); 123 | } 124 | 125 | long start = System.currentTimeMillis(); 126 | 127 | ArrayList evaluateThreads = new ArrayList(); 128 | Client client; 129 | for (int i = 0; i < clients.size(); i++) { 130 | client = clients.get(i); 131 | Thread thread = ((bench == 0) ? new Evaluate(client, operations) : new Throughput(client, operations)); 132 | thread.start(); 133 | evaluateThreads.add(thread); 134 | } 135 | 136 | for (int i = 0; i < clients.size(); i++) { 137 | evaluateThreads.get(i).join(); 138 | } 139 | 140 | System.out.println("\n================================================================="); 141 | System.out.println("Overall Time for doing " + operations 142 | + " operations with " + clients.size() +" clients " 143 | + (System.currentTimeMillis() - start) + " ms."); 144 | System.out.println("================================================================="); 145 | 146 | } 147 | 148 | } 149 | -------------------------------------------------------------------------------- /src/node/Peer.java: -------------------------------------------------------------------------------- 1 | package node; 2 | 3 | import java.io.IOException; 4 | import java.io.Serializable; 5 | import java.net.ServerSocket; 6 | import java.net.Socket; 7 | import java.util.ArrayList; 8 | import java.util.Hashtable; 9 | import java.util.concurrent.ExecutorService; 10 | import java.util.concurrent.Executors; 11 | 12 | import util.PeerQueue; 13 | import node.client.Connection; 14 | import node.server.OpenServer; 15 | import node.server.Server; 16 | 17 | @SuppressWarnings("serial") 18 | public class Peer implements Serializable{ 19 | 20 | private int peerId; 21 | private String address; 22 | private int port; 23 | private String directory; 24 | private ArrayList fileNames; 25 | private int numFiles; 26 | private int numThreads = 4; 27 | public ServerSocket serverSocket; 28 | 29 | private PeerQueue peerQueue; 30 | 31 | private Hashtable hashtable; 32 | 33 | public Peer(int peerId, String address, int port, String directory) 34 | throws IOException { 35 | this.peerId = peerId; 36 | this.address = address; 37 | this.port = port; 38 | 39 | hashtable = new Hashtable(); 40 | peerQueue = new PeerQueue(); 41 | } 42 | 43 | public Peer(int peerId, String address, int port, String directory, 44 | ArrayList fileNames, int numFiles) throws IOException { 45 | this.peerId = peerId; 46 | this.directory = directory; 47 | this.fileNames = fileNames; 48 | this.numFiles = numFiles; 49 | this.address = address; 50 | this.port = port; 51 | 52 | hashtable = new Hashtable(); 53 | peerQueue = new PeerQueue(); 54 | } 55 | 56 | // getters 57 | public int getPeerId() { 58 | return peerId; 59 | } 60 | 61 | public String getAddress() { 62 | return address; 63 | } 64 | 65 | public int getPort() { 66 | return port; 67 | } 68 | 69 | public Hashtable getHashtable() { 70 | return hashtable; 71 | } 72 | 73 | public int getNumFiles() { 74 | return numFiles; 75 | } 76 | 77 | public ArrayList getFileNames() { 78 | return fileNames; 79 | } 80 | 81 | public String getDirectory() { 82 | return directory; 83 | } 84 | 85 | // setters 86 | public void setPeerId(int peerId) { 87 | this.peerId = peerId; 88 | } 89 | 90 | public void setAddress(String address) { 91 | this.address = address; 92 | } 93 | 94 | public void setPort(int port) { 95 | this.port = port; 96 | } 97 | 98 | public void setHashtable(Hashtable hashtable) { 99 | this.hashtable = hashtable; 100 | } 101 | 102 | public void setNumFiles(int numFiles) { 103 | this.numFiles = numFiles; 104 | } 105 | 106 | public void setFileNames(ArrayList fileNames) { 107 | this.fileNames.addAll(fileNames); 108 | } 109 | 110 | public void addFileName(String fileName) { 111 | this.fileNames.add(fileName); 112 | } 113 | 114 | public void setDirectory(String directory) { 115 | this.directory = directory; 116 | } 117 | 118 | // Override 119 | public String toString() { 120 | return peerId + ":" + address + ":" + port + ":" + directory; 121 | } 122 | 123 | // Override 124 | public boolean equals(Object other){ 125 | if (other == null) return false; 126 | if (other == this) return true; 127 | if (!(other instanceof Peer))return false; 128 | Peer otherPeer = (Peer)other; 129 | if(otherPeer.getPeerId() == this.peerId) return true; 130 | return false; 131 | 132 | } 133 | 134 | public void openServer() throws IOException { 135 | 136 | try { 137 | serverSocket = new ServerSocket(port); 138 | } catch (Exception e) { 139 | return; 140 | } 141 | 142 | while (true) { 143 | //System.out.println("waiting for connection"); 144 | Socket socket = serverSocket.accept(); 145 | //System.out.println("connection accepted"); 146 | OpenServer os = new OpenServer(socket,directory); 147 | os.start(); 148 | } 149 | } 150 | 151 | public void server() throws IOException { 152 | 153 | try { 154 | serverSocket = new ServerSocket(port); 155 | } catch (Exception e) { 156 | return; 157 | } 158 | 159 | while (true) { 160 | System.out.println("waiting for connection"); 161 | Socket socket = serverSocket.accept(); 162 | System.out.println("connection accepted"); 163 | synchronized (peerQueue) { 164 | peerQueue.add(new Connection(socket, directory)); 165 | System.out.println("connection added"); 166 | } 167 | 168 | //try { Thread.sleep(2); } catch (InterruptedException e) { 169 | // e.printStackTrace(); } 170 | } 171 | 172 | } 173 | 174 | public void assign() throws IOException { 175 | 176 | ExecutorService executor = Executors.newFixedThreadPool(numThreads); 177 | 178 | while (true) { 179 | if (peerQueue.peek() == null) { 180 | try { 181 | Thread.sleep(1); 182 | } catch (InterruptedException e) { 183 | e.printStackTrace(); 184 | } 185 | continue; 186 | } 187 | synchronized (peerQueue) { 188 | System.out.println("Added to executor"); 189 | Connection c = peerQueue.poll(); 190 | Server s = new Server(c.getSocket(), c.getDirectory()); 191 | executor.execute(s); 192 | System.out.println("Executed"); 193 | } 194 | } 195 | 196 | } 197 | 198 | } 199 | -------------------------------------------------------------------------------- /src/node/client/Client.java: -------------------------------------------------------------------------------- 1 | package node.client; 2 | 3 | import index.server.Assign; 4 | import index.server.IndexingServer; 5 | 6 | import java.io.DataInputStream; 7 | import java.io.DataOutputStream; 8 | import java.io.File; 9 | import java.io.FileInputStream; 10 | import java.io.FileOutputStream; 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | import java.io.ObjectInputStream; 14 | import java.io.OutputStream; 15 | import java.net.ServerSocket; 16 | import java.net.Socket; 17 | import java.util.ArrayList; 18 | import java.util.Random; 19 | import java.util.Scanner; 20 | 21 | import node.Peer; 22 | import util.DistributedHashtable; 23 | import util.Util; 24 | 25 | public class Client extends Thread { 26 | 27 | private Peer peer; 28 | private static ArrayList peerList; 29 | private static ArrayList serverList; 30 | private ArrayList serverSocketList; 31 | private Socket[] peerSocketList; 32 | 33 | public Client() { 34 | try { 35 | peerList = DistributedHashtable.readConfigFile("peers"); 36 | serverList = DistributedHashtable.readConfigFile("servers"); 37 | } catch (IOException e) { 38 | e.printStackTrace(); 39 | } 40 | } 41 | 42 | public Client(Peer peer) { 43 | this.peer = peer; 44 | 45 | try { 46 | peerList = DistributedHashtable.readConfigFile("peers"); 47 | serverList = DistributedHashtable.readConfigFile("servers"); 48 | } catch (IOException e) { 49 | e.printStackTrace(); 50 | } 51 | } 52 | 53 | // getters 54 | public Peer getPeer() { 55 | return this.peer; 56 | } 57 | 58 | public ArrayList getPeerList() { 59 | return peerList; 60 | } 61 | 62 | public ArrayList getServerSocketList() { 63 | return this.serverSocketList; 64 | } 65 | 66 | public Socket[] getPeerSocketList() { 67 | return this.peerSocketList; 68 | } 69 | 70 | // setters 71 | public void setPeer(Peer peer) { 72 | this.peer = peer; 73 | } 74 | 75 | public void setPeerlist() { 76 | try { 77 | peerList = DistributedHashtable.readConfigFile("peers"); 78 | } catch (IOException e) { 79 | e.printStackTrace(); 80 | } 81 | } 82 | 83 | public void setPeerList(ArrayList peerList2) { 84 | peerList = peerList2; 85 | } 86 | 87 | public void setServerlist() { 88 | try { 89 | serverList = DistributedHashtable.readConfigFile("servers"); 90 | } catch (IOException e) { 91 | e.printStackTrace(); 92 | } 93 | } 94 | 95 | public void setServerList(ArrayList serverList2) { 96 | serverList = serverList2; 97 | } 98 | 99 | public void setServerSocketList(ArrayList serverSocketList) { 100 | this.serverSocketList = serverSocketList; 101 | } 102 | 103 | public void setPeerSocketList(Socket[] peerSocketList) { 104 | this.peerSocketList = peerSocketList; 105 | } 106 | 107 | public void addPeerSocket(Socket peerSocket, int pos) { 108 | this.peerSocketList[pos] = peerSocket; 109 | } 110 | 111 | // put 112 | public Boolean registry(boolean resilience) throws Exception { 113 | 114 | int pId; 115 | Socket socket; 116 | boolean ack = false; 117 | for (String fileName : peer.getFileNames()) { 118 | pId = DistributedHashtable.hash(fileName, serverList.size()); 119 | pId = resilience ? ((pId == serverList.size() - 1) ? 0 : pId + 1) 120 | : pId; 121 | socket = serverSocketList.get(pId); 122 | 123 | //synchronized(socket){ 124 | DataOutputStream dOut = new DataOutputStream( 125 | socket.getOutputStream()); 126 | // put option 127 | dOut.writeByte(0); 128 | dOut.flush(); 129 | 130 | // fileName, peer 131 | dOut.writeUTF(fileName); 132 | dOut.flush(); 133 | dOut.writeUTF(peer.toString()); 134 | dOut.flush(); 135 | DataInputStream dIn = new DataInputStream(socket.getInputStream()); 136 | ack = dIn.readBoolean(); 137 | if (ack == false) 138 | break; 139 | //} 140 | } 141 | 142 | return ack; 143 | } 144 | 145 | // get 146 | @SuppressWarnings("unchecked") 147 | public ArrayList search(String fileName, boolean resilience) 148 | throws IOException { 149 | 150 | int pId = DistributedHashtable.hash(fileName, serverList.size()); 151 | pId = resilience ? ((pId == serverList.size() - 1) ? 0 : pId + 1) : pId; 152 | Socket socket = serverSocketList.get(pId); 153 | 154 | //ArrayList resultList = new ArrayList(); 155 | //int numFiles; 156 | // synchronized(socket){ 157 | DataOutputStream dOut = new DataOutputStream(socket.getOutputStream()); 158 | 159 | // lookup option 160 | dOut.writeByte(1); 161 | dOut.flush(); 162 | 163 | // key 164 | dOut.writeUTF(fileName); 165 | dOut.flush(); 166 | 167 | //DataInputStream dIn = new DataInputStream(socket.getInputStream()); 168 | /*numFiles = dIn.readInt(); 169 | for (int i = 0; i < numFiles; i++) { 170 | resultList.add(dIn.readUTF()); 171 | } 172 | // }*/ 173 | ArrayList readList = null; 174 | ObjectInputStream oin = new ObjectInputStream(socket.getInputStream()); 175 | try { 176 | readList = (ArrayList) oin.readObject(); 177 | } catch (ClassNotFoundException e) { 178 | e.printStackTrace(); 179 | } 180 | 181 | 182 | return readList; 183 | } 184 | 185 | public long download(String fileName, int peerId, String peer) 186 | throws Exception { 187 | String[] peerAddress = peer.split(":"); 188 | Socket socket; 189 | if (peerSocketList[peerId] == null) { 190 | socket = new Socket(peerAddress[1], 191 | Integer.parseInt(peerAddress[2])); 192 | addPeerSocket(socket, peerId); 193 | } else { 194 | socket = getPeerSocketList()[peerId]; 195 | } 196 | 197 | //synchronized(socket){ 198 | //System.out.println("here"); 199 | DataOutputStream dOut = new DataOutputStream(socket.getOutputStream()); 200 | // download option 201 | dOut.writeByte(0); 202 | dOut.flush(); 203 | dOut.writeUTF(fileName); 204 | dOut.flush(); 205 | //System.out.println("name writen"); 206 | 207 | DataInputStream dIn = new DataInputStream(socket.getInputStream()); 208 | long fileSize = dIn.readLong(); 209 | //System.out.println("fileSize read = " + fileSize); 210 | String folder = "downloads-peer" + this.peer.getPeerId() + "/"; 211 | File f = new File(folder); 212 | Boolean created = false; 213 | if (!f.exists()) { 214 | try { 215 | created = f.mkdir(); 216 | } catch (Exception e) { 217 | System.out 218 | .println("Couldn't create the folder, the file will be saved in the current directory!"); 219 | } 220 | } else { 221 | created = true; 222 | } 223 | 224 | // if(i != -1) fileName = fileName + i; 225 | 226 | OutputStream out = (created) ? new FileOutputStream(f.toString() + "/" 227 | + fileName) : new FileOutputStream(fileName); 228 | Util.copy(dIn, out, fileSize); 229 | out.close(); 230 | //System.out.println("File " + fileName + " received from peer " + peerAddress[0] + ":" + peerAddress[1]); 231 | //} 232 | return fileSize; 233 | } 234 | 235 | public boolean startIndexingServer(int port) { 236 | ServerSocket serverSocket; 237 | try { 238 | serverSocket = new ServerSocket(port); 239 | // start server 240 | IndexingServer server = new IndexingServer(serverSocket); 241 | server.start(); 242 | 243 | // start assign 244 | Assign assign = new Assign(server); 245 | assign.start(); 246 | } catch (IOException e) { 247 | // e.printStackTrace(); 248 | return false; 249 | } 250 | 251 | return true; 252 | } 253 | 254 | public void replicateFiles(int peerId) throws Exception { 255 | String[] peerAddress = peerList.get(peerId).split(":"); 256 | Socket socket = null; 257 | if (peerSocketList[peerId] == null) { 258 | try { 259 | socket = new Socket(peerAddress[0], 260 | Integer.parseInt(peerAddress[1])); 261 | } catch (Exception e) { 262 | System.out.println("Peer " + peerId + " is down."); 263 | throw new Exception(); 264 | } 265 | addPeerSocket(socket, peerId); 266 | } else { 267 | socket = getPeerSocketList()[peerId]; 268 | } 269 | // int id; 270 | for (String fileName : peer.getFileNames()) { 271 | // id = DistributedHashtable.hash(file, peerList.size()); 272 | DataOutputStream dOut = new DataOutputStream( 273 | socket.getOutputStream()); 274 | // download option 275 | dOut.writeByte(1); 276 | dOut.flush(); 277 | dOut.writeInt(peer.getPeerId()); 278 | dOut.flush(); 279 | dOut.writeUTF(fileName); 280 | dOut.flush(); 281 | InputStream in = new FileInputStream(peer.getDirectory() + "/" 282 | + fileName); 283 | long fileSize = new File(peer.getDirectory() + "/" + fileName) 284 | .length(); 285 | dOut.writeLong(fileSize); 286 | dOut.flush(); 287 | //System.out.println("fileSize writen"); 288 | 289 | Util.copy(in, dOut, fileSize); 290 | in.close(); 291 | //System.out.println("File " + fileName + " sent for replication"); 292 | DataInputStream dIn = new DataInputStream(socket.getInputStream()); 293 | dIn.readUTF(); 294 | //System.out.println(dIn.readUTF()); 295 | //System.out.println("File sent successfuly"); 296 | //try { Thread.sleep(5); } catch (Exception e) { } 297 | } 298 | 299 | } 300 | 301 | public void userInterface() { 302 | int option, downopt, operations; 303 | String key = null; 304 | Boolean result = false; 305 | ArrayList value; 306 | 307 | int id = peer.getPeerId(); 308 | 309 | System.out.println("Runnning as Peer " + id); 310 | 311 | Scanner scanner = new Scanner(System.in); 312 | while (true) { 313 | System.out.println("\n\nSelect the option:"); 314 | System.out.println("\t1 - Registry"); 315 | System.out.println("\t2 - Search"); 316 | System.out.println("\t3 - Download"); 317 | System.out.println("\t4 - Bench"); 318 | System.out.println("\t5 - Close"); 319 | 320 | try { 321 | option = scanner.nextInt(); 322 | if (option == 1) { 323 | try { 324 | result = registry(false); 325 | result = registry(true); 326 | } catch (Exception e) { 327 | System.out.println("Couldn't registry in the system."); 328 | } 329 | 330 | while(true){ 331 | try { 332 | replicateFiles(id == peerList.size() - 1 ? 0 : id + 1); 333 | break; 334 | } catch (Exception e) { 335 | e.printStackTrace(); 336 | System.out.println("Cannot replicate, trying again..."); 337 | try { Thread.sleep(5000); } catch (Exception e1) { } 338 | } 339 | } 340 | 341 | System.out.println(result ? "Registered!" 342 | : "Not registered."); 343 | 344 | } else if (option == 2) { 345 | 346 | System.out.print("File Name: "); 347 | key = scanner.next(); 348 | 349 | try { 350 | value = search(key, false); 351 | } catch (Exception e) { 352 | try { 353 | value = search(key, true); 354 | } catch (Exception e1) { 355 | System.out 356 | .println("Something went wrong and it couldn'd find the file."); 357 | continue; 358 | } 359 | } 360 | if (value.size() == 0) { 361 | System.out.println("File not found in the system."); 362 | continue; 363 | } 364 | for (Peer s : value) { 365 | String [] res = s.toString().split(":"); 366 | System.out.println("Peer " + res[0] + " (" + res[1] +":"+ res[2] + ") has the file!"); 367 | } 368 | 369 | } else if (option == 3) { 370 | 371 | System.out.print("File Name: "); 372 | key = scanner.next(); 373 | 374 | try { 375 | value = search(key, false); 376 | } catch (Exception e) { 377 | try { 378 | value = search(key, true); 379 | } catch (Exception e1) { 380 | System.out 381 | .println("Something went wrong and it couldn'd find the file."); 382 | continue; 383 | } 384 | } 385 | if (value.size() == 0) { 386 | System.out.println("File not found in the system."); 387 | continue; 388 | } 389 | for (int i = 1; i <= value.size(); i++) { 390 | String [] res = value.get(i - 1).toString().split(":"); 391 | System.out.println("\t" + i + " - " + "Peer " + res[0] + " (" + res[1] +":"+ res[2] + ")"); 392 | 393 | } 394 | while (true) { 395 | System.out.print("Peer: "); 396 | downopt = scanner.nextInt(); 397 | if (downopt < 0 || downopt > value.size()) 398 | continue; 399 | download(key, downopt - 1, value.get(downopt - 1).toString()); 400 | System.out.println("File downloaded!"); 401 | break; 402 | } 403 | 404 | } else if (option == 4) { 405 | while (true) { 406 | System.out.print("Number of operations: "); 407 | operations = scanner.nextInt(); 408 | if (operations < 0) 409 | continue; 410 | bench(operations); 411 | System.out.println("Benchmarked!"); 412 | break; 413 | } 414 | } else if (option == 5) { 415 | System.out.println("Bye bye!"); 416 | scanner.close(); 417 | return; 418 | }else { 419 | System.out.println("Option not valid"); 420 | continue; 421 | } 422 | } catch (Exception e) { 423 | // e.printStackTrace(); 424 | System.out.println("Oops, something went wrong."); 425 | scanner = new Scanner(System.in); 426 | // break; 427 | } 428 | } 429 | } 430 | 431 | public void startServers() { 432 | new Thread() { 433 | public void run() { 434 | try { 435 | peer.server(); 436 | } catch (IOException e) { 437 | e.printStackTrace(); 438 | } 439 | } 440 | }.start(); 441 | 442 | new Thread() { 443 | public void run() { 444 | try { 445 | peer.assign(); 446 | } catch (IOException e) { 447 | e.printStackTrace(); 448 | } 449 | } 450 | }.start(); 451 | } 452 | 453 | public void startOpenServer() { 454 | new Thread() { 455 | public void run() { 456 | try { 457 | peer.openServer(); 458 | } catch (IOException e) { 459 | e.printStackTrace(); 460 | } 461 | } 462 | }.start(); 463 | } 464 | 465 | public void bench(int operations){ 466 | long start = System.currentTimeMillis(); 467 | long startTime = start; 468 | 469 | for(int i = 0; i < operations; i++){ 470 | try{ 471 | registry(false); 472 | } catch (Exception e){ 473 | e.printStackTrace(); 474 | } 475 | } 476 | 477 | System.out.println("Time for registry peer " 478 | + peer.getPeerId() + " " + operations 479 | + " times was " + (System.currentTimeMillis() - start) + " ms."); 480 | 481 | String fileName; 482 | 483 | ArrayList result; 484 | Random rand = new Random(); 485 | int j = 0; 486 | 487 | start = System.currentTimeMillis(); 488 | 489 | for(int i = 0; i < operations; i++){ 490 | //fileName = "file-p" + (j++) + "-0" + i; 491 | rand.setSeed(System.currentTimeMillis() + j++); 492 | rand.nextInt(j); 493 | fileName = "file-p" + rand.nextInt(peerList.size()) + "-0" + rand.nextInt(peer.getNumFiles()); 494 | try { 495 | search(fileName, false); 496 | } catch (Exception e) { 497 | e.printStackTrace(); 498 | } 499 | } 500 | 501 | System.out.println("Time for doing " + operations 502 | + " searches in peer " + peer.getPeerId() + " was " 503 | + (System.currentTimeMillis() - start) + " ms."); 504 | 505 | start = System.currentTimeMillis(); 506 | 507 | for(int i = 0; i < operations; i++){ 508 | //fileName = "file-p" + (j++) + "-0" + i; 509 | rand.setSeed(System.currentTimeMillis() + j++); 510 | rand.nextInt(j); 511 | fileName = "file-p" + rand.nextInt(peerList.size()) + "-0" + rand.nextInt(peer.getNumFiles()); 512 | 513 | try { 514 | result = search(fileName, false); 515 | //System.out.println(client.getPeer().toString() + " " + fileName + " " + result.size()); 516 | if(result.size() == 0){ 517 | i--; 518 | System.out.println(fileName + " " + result.size()); 519 | continue; 520 | } 521 | download(fileName, result.get(0).getPeerId(), result.get(0).toString()); 522 | } catch (Exception e) { 523 | //e.printStackTrace(); 524 | } 525 | } 526 | 527 | System.out.println("Time for doing " + operations 528 | + " downloads in peer " + peer.getPeerId() + " was " 529 | + (System.currentTimeMillis() - start) + " ms."); 530 | 531 | System.out.println("Overall Time for doing " + operations 532 | + " operations with in peer " + peer.getPeerId() + " was " 533 | + (System.currentTimeMillis() - startTime) + " ms."); 534 | } 535 | 536 | public long bench_download(int operations){ 537 | 538 | long total_bytes = 0; 539 | String fileName; 540 | 541 | ArrayList result; 542 | Random rand = new Random(); 543 | int j = 0; 544 | 545 | 546 | for(int i = 0; i < operations; i++){ 547 | //fileName = "file-p" + (j++) + "-0" + i; 548 | rand.setSeed(System.currentTimeMillis() + j++); 549 | rand.nextInt(j); 550 | fileName = "file-p" + rand.nextInt(peerList.size()) + "-0" + rand.nextInt(peer.getNumFiles()); 551 | 552 | try { 553 | result = search(fileName, false); 554 | //System.out.println(fileName + " " + result.size()); 555 | if(result.size() == 0){ 556 | System.out.println(fileName + " " + result.size()); 557 | i--; 558 | continue; 559 | } 560 | total_bytes += download(fileName, result.get(0).getPeerId(), result.get(0).toString()); 561 | } catch (Exception e) { 562 | e.printStackTrace(); 563 | } 564 | } 565 | 566 | 567 | 568 | return total_bytes; 569 | } 570 | 571 | public static void main(String[] args) throws IOException { 572 | 573 | Client c = new Client(); 574 | 575 | if (args.length < 1) { 576 | // System.out.println("Usage: java -jar build/Client.jar
"); 577 | System.out.println("Usage: java -jar build/Client.jar "); 578 | return; 579 | } 580 | 581 | int id = 0; 582 | try { 583 | id = Integer.parseInt(args[0]); 584 | } catch (Exception e) { 585 | System.out.println("Put a valid Id"); 586 | return; 587 | } 588 | 589 | if (id > peerList.size()) { 590 | System.out 591 | .println("Peer Id shouldn't be greater than the number provided in the config file!"); 592 | return; 593 | } 594 | 595 | String[] peerAddress; 596 | peerAddress = peerList.get(id).split(":"); 597 | String address = peerAddress[0]; 598 | int port = Integer.parseInt(peerAddress[1]); 599 | 600 | // String dir = args[3]; 601 | String dir = peerAddress[2]; 602 | File folder = new File(dir); 603 | 604 | if (!folder.isDirectory()) { 605 | System.out.println("Put a valid directory name"); 606 | return; 607 | } 608 | 609 | ArrayList fileNames = Util.listFilesForFolder(folder); 610 | final Peer peer = new Peer(id, address, port, dir, fileNames, 611 | fileNames.size()); 612 | 613 | String[] serverAddress; 614 | 615 | ArrayList serverSocketList = new ArrayList(); 616 | 617 | 618 | c.setPeer(peer); 619 | // startServers(); 620 | c.startOpenServer(); 621 | 622 | int i; 623 | // checking if all are open 624 | for (i = 0; i < serverList.size(); i++) { 625 | serverAddress = serverList.get(i).split(":"); 626 | address = serverAddress[0]; 627 | port = Integer.parseInt(serverAddress[1]); 628 | 629 | try { 630 | System.out.println("Testing connection to server " + address 631 | + ":" + port); 632 | Socket s = new Socket(address, port); 633 | serverSocketList.add(s); 634 | System.out.println("Server " + address + ":" + port 635 | + " is running."); 636 | } catch (Exception e) { 637 | // System.out.println("Not connected to server " + address + ":" 638 | // + port); 639 | // System.out.println("Trying again"); 640 | i--; 641 | port--; 642 | } 643 | } 644 | c.setServerSocketList(serverSocketList); 645 | 646 | c.setPeerSocketList(new Socket[peerList.size()]); 647 | 648 | c.userInterface(); 649 | System.exit(1); 650 | } 651 | 652 | } 653 | --------------------------------------------------------------------------------