-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTracker.java
180 lines (151 loc) · 5.47 KB
/
Tracker.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
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Random;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import java.lang.Thread;
public class Tracker {
private ServerSocket server;
// Data
private List<SavedPeer> savedPeers;
private List<LoggedInPeer> loggedInPeers;
private List<Integer> tokens; // A list for holding all active token ids
// This hashmap holds a peer's username with his files' names
private ConcurrentHashMap<String, ArrayList<SavedFile>> peerFiles;
public Tracker() {
savedPeers = new ArrayList<>();
loggedInPeers = new ArrayList<>();
tokens = new ArrayList<>();
peerFiles = new ConcurrentHashMap<>();
start();
}
private void start() {
try {
// Open server socket at port 55217
server = new ServerSocket(55217);
System.out.println("Tracker: Online and listening at port 55217.");
while (true) {
// Wait for clients
Socket socket = server.accept();
// The tracker uses threads to process each client individualy
Thread thread = new Thread(new MessageHandler(socket, this));
thread.start();
}
} catch (IOException ioe) {
ioe.printStackTrace();
System.exit(0);
}
}
// Try to create a new peer. If the peer's username already exists return false.
public synchronized boolean addSavedPeer(String username, String password) {
for (SavedPeer peer : savedPeers) {
if (peer.getUsername().equals(username))
return false;
}
savedPeers.add(new SavedPeer(username, password));
return true;
}
// Return the token_id if succefull. Otherwise, return 0
public synchronized int loginPeer(String username, String password, int port, Socket socket,
ObjectOutputStream output, ObjectInputStream input) {
// Make sure the peer is registered
boolean found = false;
SavedPeer user = null;
for (SavedPeer peer : savedPeers) {
if (peer.getUsername().equals(username)) {
found = true;
user = peer;
break;
}
}
if (!found || !password.equals(user.getPassword())) return 0;
// Create LoggedInPeer instance
int token = getNewTokenId();
tokens.add(token);
loggedInPeers.add(new LoggedInPeer(token, port, socket, output, input, user));
return token;
}
public synchronized void addPeerFiles(String username, ArrayList<SavedFile> files) {
peerFiles.put(username, files);
// Find the user and add the new files to his existing ones
for (SavedPeer user : savedPeers) {
if (user.getUsername().equals(username)) {
for (SavedFile file : files)
user.addFile(file);
break;
}
}
}
public synchronized void logoutPeer(int token) {
tokens.remove(Integer.valueOf(token));
for (LoggedInPeer peer : loggedInPeers) {
if (peer.getTokenId() == (token)) {
loggedInPeers.remove(peer);
break;
}
}
}
// Given a token_id, return the username associated with that user
public String getUsername(String token) {
for (LoggedInPeer user : loggedInPeers) {
if (String.valueOf(user.getTokenId()).equals(token))
return user.getUser().getUsername();
}
return null;
}
// Return a list containing all files available
public List<String> getAllFiles() {
List<String> allFiles = new ArrayList<>();
for (String username : peerFiles.keySet()) {
for (SavedFile file : peerFiles.get(username)) {
if (!allFiles.contains(file.getFilename()))
allFiles.add(file.getFilename());
}
}
return allFiles;
}
private int getNewTokenId() {
int token = 0;
Random rand = new Random();
boolean unique = false;
while (!unique) {
token = rand.nextInt();
if (token == 0)
token++; // token_id can't be zero
// Find if there is a similar token id
unique = true;
for (int i = 0; i < tokens.size(); i++) {
if (token == tokens.get(i))
unique = false;
}
}
return token;
}
// Getters and setters
public List<SavedPeer> getSavedPeers() {
return savedPeers;
}
public List<Integer> getTokens() {
return tokens;
}
public List<LoggedInPeer> getLoggedInPeers() {
return loggedInPeers;
}
public ConcurrentHashMap<String, ArrayList<SavedFile>> getPeerFiles() {
return new ConcurrentHashMap<>(peerFiles);
}
public synchronized void setPeerFiles(ConcurrentHashMap<String, ArrayList<SavedFile>> peerFiles) {
this.peerFiles = peerFiles;
}
public synchronized void addPeerFile(String token, SavedFile file) {
peerFiles.putIfAbsent(token, new ArrayList<>());
peerFiles.get(token).add(file);
}
public static void main(String[] args) {
new Tracker();
}
}