Projet_JAVA_P2P_STRI2A/src/serverP2P/ServerManagementTCP.java
Louis Royer 23586561a0
Some checks are pending
flavien's git/Projet_JAVA_P2P_STRI2A/pipeline/head This commit looks good
flavien's git/Projet_JAVA_P2P_STRI2A/pipeline/pr-master Build started...
Split ClientManagement
into ClientInterface and ClientManagement
2020-04-09 11:45:40 +02:00

191 lines
5.5 KiB
Java

package serverP2P;
import java.util.Vector;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.SocketException;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.net.ServerSocket;
import java.net.Socket;
import protocolP2P.ProtocolP2PPacketTCP;
import protocolP2P.ProtocolP2PPacket;
import protocolP2P.RequestResponseCode;
import protocolP2P.Payload;
import protocolP2P.LoadRequest;
import protocolP2P.FileList;
import protocolP2P.FilePart;
import localException.InternalError;
import localException.ProtocolError;
import localException.SizeError;
import localException.TransmissionError;
import localException.VersionError;
import localException.SocketClosed;
import exception.LocalException;
import java.util.Arrays;
import tools.Logger;
import tools.LogLevel;
import tools.HostItem;
import java.util.HashMap;
import java.util.Map;
import java.net.UnknownHostException;
import protocolP2P.HashAlgorithm;
import protocolP2P.HashRequest;
import protocolP2P.HashResponse;
import protocolP2P.Register;
import protocolP2P.Unregister;
import serverP2P.ServerManagement;
import serverP2P.FileWatcherTCP;
/** Implementation of P2P-JAVA-PROJECT VERSION 1.0 protocol for TCP.
* @author Louis Royer
* @author Flavien Haas
* @author JS Auge
* @version 1.0
*/
public class ServerManagementTCP extends ServerManagement {
private ServerSocket socket;
/** Constructor for TCP implementation, with baseDirectory and TCPPort parameters.
* @param baseDirectory the root directory where files are stored
* @param hostName the server will bind on this address
* @param TCPPort the server will listen on this port
* @param logger Logger item
* @param tracker Tracker
*/
public ServerManagementTCP(String baseDirectory, HostItem server, HostItem tracker, Logger logger) {
super(baseDirectory, server, tracker, logger);
assert baseDirectory != null : "baseDirectory is null";
assert server != null : "server is null";
assert tracker != null : "tracker is null";
assert logger != null : "logger is null";
try {
socket = new ServerSocket(server.getPort(), 10, server.getInetAddress());
} catch (SocketException e) {
writeLog("Error: cannot listen on " + server, LogLevel.Error);
System.exit(-1);
} catch (IOException e) {
writeLog("Error: cannot openning socket", LogLevel.Error);
System.exit(-2);
}
}
/** Implementation of runnable. This methods allows to run the server.
*/
public void run() {
writeLog("Server sucessfully started", LogLevel.Info);
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
sendUnregisterRequest();
}
});
fileListWatcher = (FileWatcher)new FileWatcherTCP(logger, 10000, server, tracker, baseDirectory); // checking every 10 seconds
Thread flwt = new Thread(fileListWatcher);
flwt.start();
fileListWatcher.setThread(flwt);
ratioWatcher = (RatioWatcher)new RatioWatcherTCP(logger, 10000, tracker);
Thread rwt = new Thread(ratioWatcher);
rwt.start();
ratioWatcher.setThread(rwt);
while(!stop) {
try {
Socket s = socket.accept();
ClientHandler c = new ClientHandler(s);
(new Thread(c)).start();
} catch (IOException e) {
writeLog("Socket has been closed", LogLevel.Info);
}
}
writeLog("Server end of loop", LogLevel.Debug);
}
/** Private runnable class allowing to serve one client.
*/
private class ClientHandler implements Runnable {
private HostItem addr;
/** Constructor with a socket.
* @param s Socket of this client
*/
public ClientHandler(Socket s) {
addr = new HostItem(s);
}
/** Implementation of runnable. This method allow to serve one client.
*/
public void run() {
boolean end = false;
writeLog("[" + addr + "] New connection", LogLevel.Action);
do {
end = handleClientRequest();
} while(!end);
writeLog("[" + 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 handleClientRequest() {
try {
ProtocolP2PPacketTCP<?> pd = new ProtocolP2PPacketTCP<>((Object)addr.getTCPSocket());
handleRequest(pd);
} catch (IOException e) {
return true;
} catch (SocketClosed e) {
return true;
}
catch (LocalException e) {}
return false;
}
}
/** Implementation of writeLog
* @param text Text to log
* @param logLevel level of logging
*/
protected void writeLog(String text, LogLevel logLevel) {
logger.writeTCP(text, logLevel);
}
/** Implementation of writeLog
* @param e exception to log
* @param logLevel level of logging
*/
protected void writeLog(Exception e, LogLevel logLevel) {
logger.writeTCP(e, logLevel);
}
/** Create packets
* @param payload Payload
*/
protected < T extends Payload > ProtocolP2PPacket<T> createProtocolP2PPacket(T payload) {
return (ProtocolP2PPacket<T>)new ProtocolP2PPacketTCP<T>(payload);
}
/** Getter for tracker socket
* @return Tracker's socket
* @throws SocketException
* @throws UnknownHostException
* @throws IOException
*/
protected Object getTrackerSocket() throws SocketException, UnknownHostException, IOException {
return (Object)tracker.tryGetTCPSocket();
}
/** Closes socket */
protected void closeSocket() {
try {
socket.close();
} catch (IOException e) {
writeLog("Could not close socket", LogLevel.Error);
}
}
}