forked from rartner/p2pfs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathClientImpl.java
193 lines (169 loc) · 5.51 KB
/
ClientImpl.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
import java.net.*;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.util.*;
import java.io.*;
import java.nio.file.*;
import broadcast.BroadcastServer;
import broadcast.Peer;
import broadcast.Config;
/*
* IDEA Usar portas diferentes (pre-definidas) em diferentes ServerSockets
* p/ diferentes tipos de requisicoes. Vamos usar TCP ou UDP?
*/
public class ClientImpl {
private LinkedList<String> peers;
private Hashtable<String,Metadata> metadados = new Hashtable<String, Metadata>();
public static String addr;
private BroadcastServer service;
private ChunkServer chunkServer;
private Scanner scanner = new Scanner(System.in);
private FileHandler fileHandler = new FileHandler();
public ClientImpl () throws IOException, ClassNotFoundException {
}
public void run() {
try {
metadados = fileHandler.recoverMetadata();
URL url = new URL("http://"+ Config.wsIp + ":9876/p2pfs?wsdl");
QName qname = new QName("http://broadcast/", "BroadcastServerImplService");
addr = getIp();
chunkServer = new ChunkServer(addr);
Service ws = Service.create(url, qname);
service = ws.getPort(BroadcastServer.class);
service.helloPeer(addr);
BroadcastServer service = ws.getPort(BroadcastServer.class);
new Thread (getPeerList).start();
//peers.remove(addr); // pode causar exception
//System.out.println(peers.toString());
//serializeMetadata();
//readFileToBytes(service);
//service.byePeer("teste");
//serializeMetadata();
//System.out.println("::");
while(true) {
menu();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void menu () throws IOException, ClassNotFoundException, InterruptedException {
int opt = -1;
System.out.println("\n1 - Armazenar arquivo.\n2 - Requisitar arquivo.\n3 - Listar arquivos.");
System.out.println("0 - Sair.\n");
opt = Integer.parseInt(scanner.nextLine());
switch (opt) {
case 1:
storeFile();
break;
case 2:
requestFile();
break;
case 3:
listFiles();
break;
case 0:
logout();
break;
default:
System.out.println("Opcao invalida.");
}
}
// Le um arquivo, transforma em chunks, envia aos peers e serializa
// Hashtable de metadados apos termino das operacoes.
// IDEA Paralelizar envio de chunks aos peers.
// TODO Armazenar apenas nome do arquivo caso usuario passe um caminho.
// Ex. /tmp/teste.txt (guardar apenas teste.txt)
private boolean storeFile() throws IOException, ClassNotFoundException, NoSuchFileException, DirectoryNotEmptyException, InterruptedException {
System.out.println("Insira o caminho para o arquivo.");
String filename = scanner.nextLine();
File file = new File(filename);
if(!file.exists()) {
System.out.println("Arquivo nao existe.");
return false;
}
Metadata tmp = fileHandler.readFileToBytes(file);
chunkServer.deliverChunksToPeers(tmp, peers); // Envia chunks aos peers
fileHandler.serializeMetadata(tmp); // Serializa o arquivo .sdi p/ persistencia de metadados
metadados.put(tmp.getFilename(), tmp); // Coloca metadado numa hashtable
Files.delete(Paths.get(filename)); // Deleta arquivo original
return true;
}
private boolean requestFile() throws FileNotFoundException, IOException, ClassNotFoundException {
System.out.println("Insira o nome do arquivo a ser requisitado.");
String filename = scanner.nextLine();
if (!metadados.containsKey(filename)) return false;
Metadata meta = metadados.get(filename);
LinkedList<Data> dataList = new LinkedList<Data>();
try{
for (Data d : meta.getChunks()) {
System.out.println(d.toString());
Data tmp = chunkServer.requestChunk(d.getHashChunk(), d.getPeers());
if (tmp != null)
dataList.add(tmp); // Pode dar exception!
}
} catch (NullPointerException e) {
e.printStackTrace();
}
fileHandler.restoreFile(dataList, filename);
// IDEA Pra cada chunk, seta de volta o byte[] (que foi deletado na
// hora de enviar pros peers). Com todos os chunks reconstruimos o
// arquivo e gg.
// TODO Reconstruir arquivo a partir da lista de chunks
return true;
}
// Faz requisicao de um chunk
// @params hash_chunk, peers (hash do chunk e lista de peers que possuem o chunk)
// Lista os nomes de arquivos de um cliente.
private void listFiles() {
Set<String> keys = metadados.keySet();
System.out.println();
for(String key : keys){
System.out.println(key);
}
System.out.println();
}
private void logout() {
service.byePeer(addr);
System.exit(0);
}
private Runnable getPeerList = new Runnable () {
public void run() {
try {
while (true) {
peers = service.getPeers(addr);
//System.out.println(peers.toString());
Thread.sleep(3000);
}
} catch (Exception e) {}
}
};
public String getExtIp() throws Exception {
URL whatismyip = new URL("http://checkip.amazonaws.com");
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(
whatismyip.openStream()));
String ip = in.readLine();
return ip;
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public String getIp() throws Exception {
String ret = null;
try {
InetAddress ipAddr = InetAddress.getLocalHost();
ret = ipAddr.getHostAddress();
} catch (UnknownHostException ex) {
ex.printStackTrace();
}
return ret;
}
}