Add tracker
parent
5c89bc6957
commit
6d7fabaf1c
@ -0,0 +1,47 @@
|
|||||||
|
package tracker;
|
||||||
|
import tracker.TrackerManagementTCP;
|
||||||
|
import tracker.TrackerManagementUDP;
|
||||||
|
import tools.Directories;
|
||||||
|
import tools.Logger;
|
||||||
|
|
||||||
|
/** Tracker implementation
|
||||||
|
* First argument of main method is port listened by the tracker, and is mandatory.
|
||||||
|
* @author Louis Royer
|
||||||
|
* @author Flavien Haas
|
||||||
|
* @author JS Auge
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class Tracker {
|
||||||
|
private int port;
|
||||||
|
private Directories directories;
|
||||||
|
private Logger logger;
|
||||||
|
|
||||||
|
/** Constructor with portStr containing a port number.
|
||||||
|
* @param portStr String containing port number of listening.
|
||||||
|
*/
|
||||||
|
public Tracker(String portStr) {
|
||||||
|
port = Integer.valueOf(Integer.parseInt(portStr));
|
||||||
|
directories = new Directories("P2P_JAVA_PROJECT_TRACKER_" + port);
|
||||||
|
logger = new Logger(directories.getDataHomeDirectory() + "tracker.log");
|
||||||
|
System.out.println("Tracker will listen on port " + port + " and write logs into " + directories.getDataHomeDirectory());
|
||||||
|
directories.askOpenDataHomeDirectory(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Main program entry point
|
||||||
|
* first parameter is port number and is mandatory
|
||||||
|
* to test, run with: java -ea serverP2P.ServerP2P -- <portNumber>
|
||||||
|
* @param args parameters
|
||||||
|
*/
|
||||||
|
public static void main(String [] args) {
|
||||||
|
Tracker t = new Tracker(args[1]);
|
||||||
|
TrackerManagementUDP tmudp = new TrackerManagementUDP(t.port, t.logger);
|
||||||
|
TrackerManagementTCP tmtcp = new TrackerManagementTCP(t.port, t.logger);
|
||||||
|
Thread tudp = new Thread(tmudp);
|
||||||
|
tudp.setName("Tracker UDP P2P-JAVA-PROJECT");
|
||||||
|
tudp.start();
|
||||||
|
Thread ttcp = new Thread(tmtcp);
|
||||||
|
ttcp.setName("Tracker TCP P2P-JAVA-PROJECT");
|
||||||
|
ttcp.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,270 @@
|
|||||||
|
package tracker;
|
||||||
|
import tools.Logger;
|
||||||
|
import tools.LogLevel;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import protocolP2P.ProtocolP2PPacketTCP;
|
||||||
|
import protocolP2P.ProtocolP2PPacket;
|
||||||
|
import protocolP2P.RequestResponseCode;
|
||||||
|
import protocolP2P.Payload;
|
||||||
|
import tools.HostItem;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.io.IOException;
|
||||||
|
import exception.LocalException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import protocolP2P.DiscoverRequest;
|
||||||
|
import protocolP2P.DiscoverResponse;
|
||||||
|
import protocolP2P.FileList;
|
||||||
|
import protocolP2P.HashRequest;
|
||||||
|
import localException.InternalError;
|
||||||
|
|
||||||
|
|
||||||
|
/** Tracker management implementation with tcp
|
||||||
|
* @author Louis Royer
|
||||||
|
* @author Flavien Haas
|
||||||
|
* @author JS Auge
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class TrackerManagementTCP implements Runnable {
|
||||||
|
|
||||||
|
private int port;
|
||||||
|
private Logger logger;
|
||||||
|
private ServerSocket socket;
|
||||||
|
private List<HostItem> hostList = new ArrayList<>();
|
||||||
|
private Map<String, List<HostItem>> fileList = new HashMap<>();
|
||||||
|
|
||||||
|
/** Constructor with port and logger.
|
||||||
|
* @param port Port used to listen.
|
||||||
|
* @param logger Logger object
|
||||||
|
*/
|
||||||
|
public TrackerManagementTCP(int port, Logger logger) {
|
||||||
|
this.port = port;
|
||||||
|
this.logger = logger;
|
||||||
|
try {
|
||||||
|
socket = new ServerSocket(port);
|
||||||
|
} catch (SocketException e) {
|
||||||
|
logger.writeTCP("Error: cannot listen on port " + port, LogLevel.Error);
|
||||||
|
System.exit(-1);
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.writeTCP("Error: cannot openning socket", LogLevel.Error);
|
||||||
|
System.exit(-2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Implementation of runnable. This methods allows to run the server.
|
||||||
|
*/
|
||||||
|
public void run() {
|
||||||
|
logger.writeTCP("Tracker sucessfully started", LogLevel.Info);
|
||||||
|
do {
|
||||||
|
try {
|
||||||
|
Socket s = socket.accept();
|
||||||
|
ClientHandler c = new ClientHandler(s);
|
||||||
|
(new Thread(c)).start();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.writeTCP("Error while accepting new connection", LogLevel.Warning);
|
||||||
|
}
|
||||||
|
} while(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Private runnable class allowing to serve one client.
|
||||||
|
*/
|
||||||
|
private class ClientHandler implements Runnable {
|
||||||
|
private Socket s;
|
||||||
|
private String addr;
|
||||||
|
/** Constructor with a socket.
|
||||||
|
* @param s Socket of this client
|
||||||
|
*/
|
||||||
|
public ClientHandler(Socket s) {
|
||||||
|
this.s = s;
|
||||||
|
this.addr = "[" +s.getInetAddress().getHostAddress() + "]:" + s.getPort() + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Implementation of runnable. This method allow to serve one client.
|
||||||
|
*/
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
boolean end = false;
|
||||||
|
logger.writeTCP(addr + "New connection", LogLevel.Action);
|
||||||
|
do {
|
||||||
|
end = handleRequest();
|
||||||
|
} while(!end);
|
||||||
|
logger.writeTCP(addr + "End of connection", LogLevel.Action);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Respond to next request incomming on socket s.
|
||||||
|
* @param s Socket used to read request and send response
|
||||||
|
* @return true if cannot expect another request (ie, socket is closed)
|
||||||
|
*/
|
||||||
|
private boolean handleRequest() {
|
||||||
|
try {
|
||||||
|
ProtocolP2PPacketTCP pd = new ProtocolP2PPacketTCP((Object)socket);
|
||||||
|
Payload p = pd.getPayload();
|
||||||
|
switch (p.getRequestResponseCode()) {
|
||||||
|
case LOAD_REQUEST:
|
||||||
|
logger.writeTCP("Received LOAD_REQUEST from host " + pd.getHostItem() + ", sending NOT_FOUND", LogLevel.Action);
|
||||||
|
sendNotFound(pd);
|
||||||
|
break;
|
||||||
|
case LIST_REQUEST:
|
||||||
|
logger.writeTCP("Received LIST_REQUEST from host " + pd.getHostItem() + ", sending EMPTY_DIRECTORY", LogLevel.Action);
|
||||||
|
sendEmptyDirectory(pd);
|
||||||
|
break;
|
||||||
|
case HASH_REQUEST:
|
||||||
|
logger.writeTCP("Received HASH_REQUEST from host " + pd.getHostItem() + ", sending NOT_FOUND", LogLevel.Action);
|
||||||
|
sendNotFound(pd);
|
||||||
|
break;
|
||||||
|
case REGISTER:
|
||||||
|
handleRegister(pd);
|
||||||
|
break;
|
||||||
|
case UNREGISTER:
|
||||||
|
handleUnregister(pd);
|
||||||
|
break;
|
||||||
|
case DISCOVER_REQUEST:
|
||||||
|
handleDiscover(pd);
|
||||||
|
break;
|
||||||
|
case LIST_RESPONSE:
|
||||||
|
handleListResponse(pd);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logger.writeTCP("Received grabbage from host " + pd.getHostItem(), LogLevel.Action);
|
||||||
|
sendInternalError(pd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.writeTCP(e, LogLevel.Warning);
|
||||||
|
return true;
|
||||||
|
} catch (LocalException e) {
|
||||||
|
logger.writeTCP(e, LogLevel.Warning);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send a not found message.
|
||||||
|
* @param pd ProtocolP2PPacketTCP to respond
|
||||||
|
*/
|
||||||
|
private void sendNotFound(ProtocolP2PPacketTCP pd) {
|
||||||
|
try {
|
||||||
|
pd.sendResponse((ProtocolP2PPacket)new ProtocolP2PPacketTCP(new Payload(RequestResponseCode.NOT_FOUND)));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.writeTCP(e, LogLevel.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send an empty directory message.
|
||||||
|
* @param pd ProtocolP2PPacketTCP to respond
|
||||||
|
*/
|
||||||
|
private void sendEmptyDirectory(ProtocolP2PPacketTCP pd) {
|
||||||
|
try {
|
||||||
|
pd.sendResponse((ProtocolP2PPacket)new ProtocolP2PPacketTCP(new Payload(RequestResponseCode.EMPTY_DIRECTORY)));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.writeTCP(e, LogLevel.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send an internal error message.
|
||||||
|
* @param pd ProtocolP2PPacketTCP to respond
|
||||||
|
*/
|
||||||
|
private void sendInternalError(ProtocolP2PPacketTCP pd) {
|
||||||
|
logger.writeTCP("Internal Error", LogLevel.Warning);
|
||||||
|
try {
|
||||||
|
pd.sendResponse((ProtocolP2PPacket)new ProtocolP2PPacketTCP(new Payload(RequestResponseCode.INTERNAL_ERROR)));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.writeTCP(e, LogLevel.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Handle Registering
|
||||||
|
* @param pd ProtocolP2PPacketTCP to respond
|
||||||
|
* @throws InternalError
|
||||||
|
*/
|
||||||
|
private void handleRegister(ProtocolP2PPacketTCP pd) throws InternalError {
|
||||||
|
// add host to known host list
|
||||||
|
HostItem host = pd.getHostItem();
|
||||||
|
if (!hostList.contains(host)) {
|
||||||
|
hostList.add(pd.getHostItem());
|
||||||
|
}
|
||||||
|
// send a list request
|
||||||
|
try {
|
||||||
|
pd.sendResponse((ProtocolP2PPacket)new ProtocolP2PPacketTCP(new Payload(RequestResponseCode.LIST_REQUEST)));
|
||||||
|
logger.writeTCP("Received REGISTER. Adding host " + host + " to list. Sending List request", LogLevel.Action);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// remove from list because list request could not be send
|
||||||
|
hostList.remove(host);
|
||||||
|
logger.writeTCP("Aborting the add of host " + host, LogLevel.Action);
|
||||||
|
logger.writeTCP(e, LogLevel.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Handle Unregistering
|
||||||
|
* @param pd ProtocolP2PPacketTCP to respond
|
||||||
|
* @throws InternalError
|
||||||
|
*/
|
||||||
|
private void handleUnregister(ProtocolP2PPacketTCP pd) throws InternalError {
|
||||||
|
HostItem host = pd.getHostItem();
|
||||||
|
logger.writeTCP("Received UNREGISTER. Removing host " + host, LogLevel.Action);
|
||||||
|
hostList.remove(host);
|
||||||
|
for(String f: fileList.keySet()) {
|
||||||
|
fileList.get(f).remove(host);
|
||||||
|
if(fileList.get(f).isEmpty()) {
|
||||||
|
fileList.remove(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Handle Discover request
|
||||||
|
* @param pd ProtocolP2PPacketTCP to respond
|
||||||
|
* @throws InternalError
|
||||||
|
*/
|
||||||
|
private void handleDiscover(ProtocolP2PPacketTCP pd) throws InternalError {
|
||||||
|
logger.writeTCP("Received DISCOVER REQUEST from host " + pd.getHostItem(), LogLevel.Action);
|
||||||
|
Payload p = pd.getPayload();
|
||||||
|
assert p instanceof DiscoverRequest : "payload must be an instance of DiscoverRequest";
|
||||||
|
if (!(p instanceof DiscoverRequest)) {
|
||||||
|
sendInternalError(pd);
|
||||||
|
} else {
|
||||||
|
String filename = ((HashRequest)p).getFilename();
|
||||||
|
try {
|
||||||
|
pd.sendResponse((ProtocolP2PPacket)new ProtocolP2PPacketTCP((Payload)new DiscoverResponse(filename, fileList.getOrDefault(filename, hostList))));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.writeTCP(e, LogLevel.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Handle List Responses
|
||||||
|
* @param pd ProtocolP2PPacketTCP response
|
||||||
|
* @throws InternalError
|
||||||
|
*/
|
||||||
|
private void handleListResponse(ProtocolP2PPacketTCP pd) throws InternalError {
|
||||||
|
HostItem host = pd.getHostItem();
|
||||||
|
if (!hostList.contains(host)) {
|
||||||
|
logger.writeTCP("Received LIST RESPONSE from host " + host + " but it is not registered.", LogLevel.Action);
|
||||||
|
} else {
|
||||||
|
logger.writeTCP("Received LIST RESPONSE from host " + host + ": registered host.", LogLevel.Action);
|
||||||
|
Payload p = pd.getPayload();
|
||||||
|
assert p instanceof FileList: "payload must be an instance of FileList";
|
||||||
|
if (!(p instanceof FileList)) {
|
||||||
|
sendInternalError(pd);
|
||||||
|
} else {
|
||||||
|
String[] f = ((FileList)p).getFileList();
|
||||||
|
for (String file: f) {
|
||||||
|
List<HostItem> h = fileList.get(file);
|
||||||
|
if (h != null) {
|
||||||
|
if (!h.contains(host)) {
|
||||||
|
h.add(host);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
List<HostItem> emptyH = new ArrayList<>();
|
||||||
|
emptyH.add(host);
|
||||||
|
fileList.put(file, emptyH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,221 @@
|
|||||||
|
package tracker;
|
||||||
|
import tools.Logger;
|
||||||
|
import tools.LogLevel;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
|
import protocolP2P.ProtocolP2PPacketUDP;
|
||||||
|
import protocolP2P.ProtocolP2PPacket;
|
||||||
|
import protocolP2P.RequestResponseCode;
|
||||||
|
import protocolP2P.Payload;
|
||||||
|
import tools.HostItem;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import exception.LocalException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import protocolP2P.DiscoverRequest;
|
||||||
|
import protocolP2P.DiscoverResponse;
|
||||||
|
import protocolP2P.FileList;
|
||||||
|
import protocolP2P.HashRequest;
|
||||||
|
import localException.InternalError;
|
||||||
|
|
||||||
|
/** Tracker management implementation with udp
|
||||||
|
* @author Louis Royer
|
||||||
|
* @author Flavien Haas
|
||||||
|
* @author JS Auge
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class TrackerManagementUDP implements Runnable {
|
||||||
|
|
||||||
|
private int port;
|
||||||
|
private Logger logger;
|
||||||
|
private DatagramSocket socket;
|
||||||
|
private List<HostItem> hostList = new ArrayList<>();
|
||||||
|
private Map<String, List<HostItem>> fileList = new HashMap<>();
|
||||||
|
|
||||||
|
/** Constructor with port and logger.
|
||||||
|
* @param port Port used to listen.
|
||||||
|
* @param logger Logger object
|
||||||
|
*/
|
||||||
|
public TrackerManagementUDP(int port, Logger logger) {
|
||||||
|
this.port = port;
|
||||||
|
this.logger = logger;
|
||||||
|
try {
|
||||||
|
socket = new DatagramSocket(port);
|
||||||
|
} catch (SocketException e) {
|
||||||
|
logger.writeUDP("Error: cannot listen on port " + port, LogLevel.Error);
|
||||||
|
System.exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Implementation of runnable. This methods allows to run the tracker.
|
||||||
|
*/
|
||||||
|
public void run() {
|
||||||
|
logger.writeUDP("Tracker successfully started", LogLevel.Info);
|
||||||
|
while(true) {
|
||||||
|
try {
|
||||||
|
ProtocolP2PPacketUDP pd = new ProtocolP2PPacketUDP((Object)socket);
|
||||||
|
Payload p = pd.getPayload();
|
||||||
|
switch (p.getRequestResponseCode()) {
|
||||||
|
case LOAD_REQUEST:
|
||||||
|
logger.writeUDP("Received LOAD_REQUEST from host " + pd.getHostItem() + ", sending NOT_FOUND", LogLevel.Action);
|
||||||
|
sendNotFound(pd);
|
||||||
|
break;
|
||||||
|
case LIST_REQUEST:
|
||||||
|
logger.writeUDP("Received LIST_REQUEST from host " + pd.getHostItem() + ", sending EMPTY_DIRECTORY", LogLevel.Action);
|
||||||
|
sendEmptyDirectory(pd);
|
||||||
|
break;
|
||||||
|
case HASH_REQUEST:
|
||||||
|
logger.writeUDP("Received HASH_REQUEST from host " + pd.getHostItem() + ", sending NOT_FOUND", LogLevel.Action);
|
||||||
|
sendNotFound(pd);
|
||||||
|
break;
|
||||||
|
case REGISTER:
|
||||||
|
handleRegister(pd);
|
||||||
|
break;
|
||||||
|
case UNREGISTER:
|
||||||
|
handleUnregister(pd);
|
||||||
|
break;
|
||||||
|
case DISCOVER_REQUEST:
|
||||||
|
handleDiscover(pd);
|
||||||
|
break;
|
||||||
|
case LIST_RESPONSE:
|
||||||
|
handleListResponse(pd);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logger.writeUDP("Received grabbage from host " + pd.getHostItem(), LogLevel.Action);
|
||||||
|
sendInternalError(pd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.writeUDP(e, LogLevel.Warning);
|
||||||
|
} catch (LocalException e) {
|
||||||
|
logger.writeUDP(e, LogLevel.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send a not found message.
|
||||||
|
* @param pd ProtocolP2PPacketUDP to respond
|
||||||
|
*/
|
||||||
|
private void sendNotFound(ProtocolP2PPacketUDP pd) {
|
||||||
|
try {
|
||||||
|
pd.sendResponse((ProtocolP2PPacket)new ProtocolP2PPacketUDP(new Payload(RequestResponseCode.NOT_FOUND)));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.writeUDP(e, LogLevel.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send an empty directory message.
|
||||||
|
* @param pd ProtocolP2PPacketUDP to respond
|
||||||
|
*/
|
||||||
|
private void sendEmptyDirectory(ProtocolP2PPacketUDP pd) {
|
||||||
|
try {
|
||||||
|
pd.sendResponse((ProtocolP2PPacket)new ProtocolP2PPacketUDP(new Payload(RequestResponseCode.EMPTY_DIRECTORY)));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.writeUDP(e, LogLevel.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send an internal error message.
|
||||||
|
* @param pd ProtocolP2PPacketUDP to respond
|
||||||
|
*/
|
||||||
|
private void sendInternalError(ProtocolP2PPacketUDP pd) {
|
||||||
|
logger.writeUDP("Internal Error", LogLevel.Warning);
|
||||||
|
try {
|
||||||
|
pd.sendResponse((ProtocolP2PPacket)new ProtocolP2PPacketUDP(new Payload(RequestResponseCode.INTERNAL_ERROR)));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.writeUDP(e, LogLevel.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Handle Registering
|
||||||
|
* @param pd ProtocolP2PPacketUDP to respond
|
||||||
|
* @throws InternalError
|
||||||
|
*/
|
||||||
|
private void handleRegister(ProtocolP2PPacketUDP pd) throws InternalError {
|
||||||
|
// add host to known host list
|
||||||
|
HostItem host = pd.getHostItem();
|
||||||
|
if (!hostList.contains(host)) {
|
||||||
|
hostList.add(pd.getHostItem());
|
||||||
|
}
|
||||||
|
// send a list request
|
||||||
|
try {
|
||||||
|
pd.sendResponse((ProtocolP2PPacket)new ProtocolP2PPacketUDP(new Payload(RequestResponseCode.LIST_REQUEST)));
|
||||||
|
logger.writeUDP("Received REGISTER. Adding host " + host + " to list. Sending List request", LogLevel.Action);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// remove from list because list request could not be send
|
||||||
|
hostList.remove(host);
|
||||||
|
logger.writeUDP("Aborting the add of host " + host, LogLevel.Action);
|
||||||
|
logger.writeUDP(e, LogLevel.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Handle Unregistering
|
||||||
|
* @param pd ProtocolP2PPacketUDP to respond
|
||||||
|
* @throws InternalError
|
||||||
|
*/
|
||||||
|
private void handleUnregister(ProtocolP2PPacketUDP pd) throws InternalError {
|
||||||
|
HostItem host = pd.getHostItem();
|
||||||
|
logger.writeUDP("Received UNREGISTER. Removing host " + host, LogLevel.Action);
|
||||||
|
hostList.remove(host);
|
||||||
|
for(String f: fileList.keySet()) {
|
||||||
|
fileList.get(f).remove(host);
|
||||||
|
if(fileList.get(f).isEmpty()) {
|
||||||
|
fileList.remove(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Handle Discover request
|
||||||
|
* @param pd ProtocolP2PPacketUDP to respond
|
||||||
|
* @throws InternalError
|
||||||
|
*/
|
||||||
|
private void handleDiscover(ProtocolP2PPacketUDP pd) throws InternalError {
|
||||||
|
logger.writeUDP("Received DISCOVER REQUEST from host " + pd.getHostItem(), LogLevel.Action);
|
||||||
|
Payload p = pd.getPayload();
|
||||||
|
assert p instanceof DiscoverRequest : "payload must be an instance of DiscoverRequest";
|
||||||
|
if (!(p instanceof DiscoverRequest)) {
|
||||||
|
sendInternalError(pd);
|
||||||
|
} else {
|
||||||
|
String filename = ((HashRequest)p).getFilename();
|
||||||
|
try {
|
||||||
|
pd.sendResponse((ProtocolP2PPacket)new ProtocolP2PPacketUDP((Payload)new DiscoverResponse(filename, fileList.getOrDefault(filename, hostList))));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.writeUDP(e, LogLevel.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Handle List Responses
|
||||||
|
* @param pd ProtocolP2PPacketUDP response
|
||||||
|
* @throws InternalError
|
||||||
|
*/
|
||||||
|
private void handleListResponse(ProtocolP2PPacketUDP pd) throws InternalError {
|
||||||
|
HostItem host = pd.getHostItem();
|
||||||
|
if (!hostList.contains(host)) {
|
||||||
|
logger.writeUDP("Received LIST RESPONSE from host " + host + " but it is not registered.", LogLevel.Action);
|
||||||
|
} else {
|
||||||
|
logger.writeUDP("Received LIST RESPONSE from host " + host + ": registered host.", LogLevel.Action);
|
||||||
|
Payload p = pd.getPayload();
|
||||||
|
assert p instanceof FileList: "payload must be an instance of FileList";
|
||||||
|
if (!(p instanceof FileList)) {
|
||||||
|
sendInternalError(pd);
|
||||||
|
} else {
|
||||||
|
String[] f = ((FileList)p).getFileList();
|
||||||
|
for (String file: f) {
|
||||||
|
List<HostItem> h = fileList.get(file);
|
||||||
|
if (h != null) {
|
||||||
|
if (!h.contains(host)) {
|
||||||
|
h.add(host);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
List<HostItem> emptyH = new ArrayList<>();
|
||||||
|
emptyH.add(host);
|
||||||
|
fileList.put(file, emptyH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue