2008-11-14 16:38:36 +00:00
|
|
|
package zutil.network;
|
|
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
|
import java.io.FileInputStream;
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
import java.io.ObjectInputStream;
|
|
|
|
|
import java.io.ObjectOutputStream;
|
|
|
|
|
import java.io.Serializable;
|
|
|
|
|
import java.net.ServerSocket;
|
|
|
|
|
import java.net.Socket;
|
|
|
|
|
import java.net.URISyntaxException;
|
|
|
|
|
import java.security.NoSuchAlgorithmException;
|
|
|
|
|
import java.util.ArrayList;
|
2009-09-18 11:34:16 +00:00
|
|
|
import java.util.List;
|
2008-11-14 16:38:36 +00:00
|
|
|
|
2010-07-01 16:22:02 +00:00
|
|
|
import zutil.FileUtil;
|
2008-11-14 16:38:36 +00:00
|
|
|
import zutil.Hasher;
|
|
|
|
|
import zutil.MultiPrintStream;
|
|
|
|
|
|
|
|
|
|
public class UpdateServer extends Thread{
|
|
|
|
|
private ArrayList<FileHash> fileList;
|
|
|
|
|
private ServerSocket server;
|
|
|
|
|
private boolean close;
|
|
|
|
|
private String path;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Creates a UpdateServer Thread
|
|
|
|
|
*
|
|
|
|
|
* @param path The path to sync the clients with
|
|
|
|
|
* @throws IOException
|
|
|
|
|
* @throws URISyntaxException
|
|
|
|
|
* @throws NoSuchAlgorithmException
|
|
|
|
|
*/
|
|
|
|
|
public UpdateServer(int port, String path) throws Exception{
|
|
|
|
|
fileList = getFileList(path);
|
|
|
|
|
server = new ServerSocket(port);
|
|
|
|
|
close = false;
|
|
|
|
|
this.path = path;
|
|
|
|
|
|
|
|
|
|
this.start();
|
|
|
|
|
MultiPrintStream.out.println("Update Server Online!!!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void run(){
|
|
|
|
|
while (!close){
|
|
|
|
|
try {
|
|
|
|
|
new UpdateServerThread(server.accept()).start();
|
|
|
|
|
MultiPrintStream.out.println("Update Server: Client Connected!!!");
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handles all the connecting clients
|
|
|
|
|
*
|
|
|
|
|
* @author Ziver
|
|
|
|
|
*/
|
|
|
|
|
class UpdateServerThread extends Thread{
|
|
|
|
|
private ObjectOutputStream out;
|
|
|
|
|
private ObjectInputStream in;
|
|
|
|
|
private Socket client;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Creates a UpdateServerThread
|
|
|
|
|
* @param client The socket to the client
|
|
|
|
|
* @throws IOException
|
|
|
|
|
*/
|
|
|
|
|
public UpdateServerThread(Socket c) throws IOException {
|
|
|
|
|
client = c;
|
|
|
|
|
out = new ObjectOutputStream(client.getOutputStream());
|
|
|
|
|
in = new ObjectInputStream(client.getInputStream());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
|
public void run(){
|
|
|
|
|
try {
|
|
|
|
|
// receive the clients filelist
|
|
|
|
|
ArrayList<FileHash> clientFileList = (ArrayList<FileHash>)in.readObject();
|
2010-07-01 16:22:02 +00:00
|
|
|
File tmpPath = FileUtil.find(path);
|
2008-11-14 16:38:36 +00:00
|
|
|
|
|
|
|
|
for(FileHash file : fileList){
|
|
|
|
|
if(!clientFileList.contains(file)){
|
|
|
|
|
// send new file to client
|
|
|
|
|
out.writeObject(file);
|
|
|
|
|
out.flush();
|
|
|
|
|
|
|
|
|
|
// send file data
|
|
|
|
|
FileInputStream input = new FileInputStream(tmpPath.getAbsolutePath()+file.path);
|
|
|
|
|
byte[] nextBytes = new byte[client.getSendBufferSize()];
|
|
|
|
|
int bytesRead = 0;
|
|
|
|
|
while((bytesRead = input.read(nextBytes)) > 0){
|
|
|
|
|
out.write(nextBytes,0,bytesRead);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// send update done message
|
|
|
|
|
out.writeObject(new FileHash("","",0));
|
|
|
|
|
out.flush();
|
|
|
|
|
|
|
|
|
|
out.close();
|
|
|
|
|
in.close();
|
|
|
|
|
client.close();
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
MultiPrintStream.out.println("Update Server: Client Error!!! "+e.getMessage());
|
|
|
|
|
} finally {
|
|
|
|
|
MultiPrintStream.out.println("Update Server: Client Update Done!!!");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns a ArrayList with all the files in the specified folder and there
|
|
|
|
|
* MD5 hashes
|
|
|
|
|
*
|
|
|
|
|
* @param path The path to search
|
|
|
|
|
* @return A ArrayList with all the files in the path
|
|
|
|
|
* @throws URISyntaxException
|
|
|
|
|
* @throws NoSuchAlgorithmException
|
|
|
|
|
* @throws IOException
|
|
|
|
|
*/
|
|
|
|
|
public static ArrayList<FileHash> getFileList(String path) throws Exception{
|
|
|
|
|
ArrayList<FileHash> fileHash = new ArrayList<FileHash>();
|
|
|
|
|
|
2010-07-01 16:22:02 +00:00
|
|
|
List<File> files = FileUtil.search(FileUtil.find(path));
|
2008-11-14 16:38:36 +00:00
|
|
|
for(File file : files){
|
|
|
|
|
fileHash.add(new FileHash(
|
2010-07-01 16:22:02 +00:00
|
|
|
FileUtil.relativePath(file, path),
|
2008-11-14 16:38:36 +00:00
|
|
|
Hasher.hash(file, "MD5"),
|
|
|
|
|
file.length()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return fileHash;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This class is used to store the files
|
|
|
|
|
* and there hashes
|
|
|
|
|
*
|
|
|
|
|
* @author Ziver
|
|
|
|
|
*/
|
|
|
|
|
class FileHash implements Serializable{
|
|
|
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
|
|
|
|
|
|
public String path;
|
|
|
|
|
public String hash;
|
|
|
|
|
public long size;
|
|
|
|
|
|
|
|
|
|
public FileHash(String p, String h, long s){
|
|
|
|
|
path = p;
|
|
|
|
|
hash = h;
|
|
|
|
|
size = s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean equals(Object comp){
|
|
|
|
|
FileHash tmp = (FileHash)comp;
|
|
|
|
|
return path.equals(tmp.path) && hash.equals(tmp.hash);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String toString(){
|
|
|
|
|
return path;
|
|
|
|
|
}
|
|
|
|
|
}
|