Ajout de buffer pour optimiser client/serveur
Bonjour,
En fait dans le cadre d'une application distribuée qui doit etre aussi rapide que possible j'ai réalisé une classe serveur qui attend un fichier et une classe client qui lui envoit.
Le problème est que mon code n'est pas rapide du tout :( ca met 30seconde pour enoyer 1mo en localhost:? , j'ai essayé d'ajouté des buffers mais je n'ai pas réussi :( si vous pouviez m'aider, mon code se trouve ici en desssous,
Egalement le serveur à besoin de savoir le nom du fichier qu'il recoit, en fait j'ouvre et referme le socket pour écrire dedans parceque autrement le fichier une fois reconsitué du coté serveur n'est plus ouvrable (pour le bmp).8O
Merci d'avance pour vos conseils ou remarque:P
Code:
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
|
package src.utils.FileTransfer;
import java.io.*;
import java.net.*;
/*
* Classe qui permet d'envoyer un fichier par TCP
*/
public class TCPClientFile2 extends Thread {
private Socket socket;
private final static int END_OF_FLUX=-1;
String fileNameAndPath="";
private String destinationIP;
private int destinationPort;
//private String filePath;
private String file2NameTransfert;
private DataInputStream dis=null;
private int whoIam=-1; //permet de savoir quel application l'envoit
//Ouvre le flux sur le fichier à lire pour lire ses bytes
private void openInputStream() throws FileNotFoundException{
this.dis = new DataInputStream(new FileInputStream(fileNameAndPath));
}
//Ferme le flux sur le fichier qu'on à lu
//Ferme le socket
private void closeStreams(){
try{
this.dis.close();
socket.close();
System.out.println("[CLIENT] Streams are closed");
}
catch(IOException io){System.out.println("IOEcxception while closing inputFile"+io.getMessage());}
}
//Lit le byte suivant dans le fichier
//PRE: on doit avoir fait open
//nb pas oublier de close qd on a tt lu ;)
private int readNextByteToTransfert() throws Exception{
int byteLu=0;
byteLu = dis.read();
//System.out.println("lu >"+byteLu);
return byteLu;
}
public TCPClientFile2(String destinationIP,int destinationPort,String file2NameTransfert,int iam){
System.out.println("I'am going to push the file ("+file2NameTransfert+") into to server ("+destinationIP+") who is waiting for on port ("+destinationPort+")");
this.destinationIP=destinationIP;
this.destinationPort=destinationPort;
//this.filePath=filePath;
this.file2NameTransfert=file2NameTransfert;
this.fileNameAndPath="";
this.whoIam=iam;
this.start();
}
public void run(){
try{
// Si c'est le CLIENT il envoit pov au dispatcher
if (this.whoIam==src.utils.FileTransfer.ConfigFileSender.IAM_CLIENT){
System.out.println("[SERVER] I'am a client will send .pov file");
this.fileNameAndPath=src.client.ConfigClient.PATH_CLI_POV_OUT+this.file2NameTransfert;
}
//si c'est le WORKER il envoit BMP au client
if (this.whoIam==src.utils.FileTransfer.ConfigFileSender.IAM_WORKER){
System.out.println("[SERVER] I'am a worker will send .bmp ");
this.fileNameAndPath=src.worker.ConfigWorker.PATH_WORKER_BMP_OUT+this.file2NameTransfert;
}
//si c'est le DISPATCHER il envoit pov au WORKER
if (this.whoIam==src.utils.FileTransfer.ConfigFileSender.IAM_DISPATCHER){
System.out.println("[SERVER] I'am a dispatcher waiting for a .pov file");
this.fileNameAndPath=src.dispatcher.ConfigDispatcher.PATH_DISP_POV_IN+this.file2NameTransfert;
}
//Ouverture du socket vers le server on va envoyer d'abord le nom.
System.out.println("Client ouvre socket pour envoyer le nom");
socket = new Socket(destinationIP,destinationPort);
DataOutputStream nameOut = new DataOutputStream(socket.getOutputStream());
System.out.println("Nom envoyé"+file2NameTransfert);
nameOut.writeUTF(this.file2NameTransfert);
socket.close();
System.out.println("socket pour nom fermé");
int byteLu=0;
//ouverture du flux à lire
long nbrSecDeb = java.lang.System.currentTimeMillis();
this.openInputStream();
//Ouverture du socket vers le server
socket = new Socket(destinationIP,destinationPort);
System.out.println("Socket pour byte ouvert");
//Création du flux de sortie permettant l'envoie des données.
DataOutputStream dataOut = new DataOutputStream(socket.getOutputStream());
//Création d"un buffer de 4K
//byte[] buffer= new byte[4096];
//TODO AJOUTER UN BUFFER POUR TRANSFERER!!!BYTE A BYTE CA PUE!!
//int bytesReadInFile = 0;
byteLu =this.readNextByteToTransfert();
while(byteLu != END_OF_FLUX){
//dataOut.write(buffer, 0, byteLu);
dataOut.write(byteLu);
//System.out.println("[Client] write in the socket >"+byteLu);
byteLu =this.readNextByteToTransfert();
}
// On ferme tous les flux, le socket, le fichier
long nbrSecEnd = java.lang.System.currentTimeMillis();
nbrSecEnd = nbrSecEnd-nbrSecDeb;
this.closeStreams();
System.out.println("[CLIENT] time to transfert : "+nbrSecEnd/1000 +" seconds");
}
catch(FileNotFoundException f){System.out.println("File not found exception"+f.getMessage());}
catch(IOException io){System.out.println("IOException"+io.getMessage());}
catch(Exception e){System.out.println("Exception"+e.getMessage());}
this.closeStreams();
}
public static void main(String[] args) {
try{
//TES1 OK
//System.out.println("Je suis client j'envois le pov au dispatcher");
//TCPClientFile2 t2 = new TCPClientFile2("localhost",45678,"b.pov",ConfigFileSender.IAM_CLIENT);
//TEST2 OK
System.out.println("Je suis dispatcher j'envois le pov au worker");
TCPClientFile2 t2 = new TCPClientFile2("localhost",55555,"127.0.0.1-13-0-45678-800-600-1-0-800-1-10.pov",ConfigFileSender.IAM_DISPATCHER);
//TEST3 OK
//System.out.println("Je suis worker j'envois le bmp au client");
//TCPClientFile2 t2 = new TCPClientFile2("localhost",45678,"b.bmp",ConfigFileSender.IAM_WORKER);
}
catch (Exception e){
e.printStackTrace();
}
}
} |
Code:
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 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
|
package src.utils.FileTransfer;
import java.io.*;
import java.net.*;
import src.dispatcher.GestionnaireWorkers.GestionnaireTask;
import src.client.TaskList2.TaskList2;
import src.utils.Fragment;
public class TCPServerFile2 extends Thread{
/*
*Receveur écoute et recoit...
*Non blocant, laisse le programme continuer son flux d'éxécution
*
* Ouvre un socket d'écoute pour le nom du fichier sur le port indiqué
* Lit le nom
* Ferme le socket
*
* Ouvre flux d'output pour écrire ds ce fichier
* Ouvre le flux d'input pour lire dans le socket
* Ecrit tout
* Se termine tout seul une fois le fichier recu
*/
private ServerSocket socketListener;
private DataInputStream dataInputStream;
DataOutputStream dataOutputStream;
private Socket socket;
private static final int END_OF_FLUX = -1;
private int port;//port surlequel il écoute
private int whoIam=-1;
private String outPutPathAndFileName="";
private void openStreams() throws FileNotFoundException,IOException{
System.out.print("[SERVER] opening streams...");
this.dataInputStream = new DataInputStream(this.socket.getInputStream());
this.dataOutputStream = new DataOutputStream(new FileOutputStream(outPutPathAndFileName));
System.out.println("done streams are open... receing byte will go into > "+outPutPathAndFileName);
}
public void closeStream(){
try{
System.out.print("[SERVER] closing streams...");
this.dataInputStream.close();
this.dataOutputStream.close();
this.socket.close();
this.socketListener.close();
System.out.println("done");
}
catch(Exception e){ System.out.println("Exception while closing flux..."+e.getMessage());}
}
public TCPServerFile2(int port,int whoIam1){
this.port=port;
this.whoIam=whoIam1;
this.start();
}
public void run(){
int nextByte=9999;//on initialise à tt sauf -1
try{
/*
* Ouverture du socket pour que le server connaisse le nom de ce qu'il recoit
*/
socketListener = new ServerSocket(port);
System.out.println("[SERVER] Socket created, listening on port for knowing the file Name >"+port);
socket = socketListener.accept();
dataInputStream = new DataInputStream(this.socket.getInputStream());
String incomingFileName = (String)dataInputStream.readUTF();
System.out.println("fileName"+incomingFileName);
socketListener.close();
socket.close();
//Si c'est le CLIENT qui recoit c'est pour avoir un bmp
if (this.whoIam==src.utils.FileTransfer.ConfigFileSender.IAM_CLIENT){
System.out.println("[SERVER] I'am a client waiting for a .bmp file");
this.outPutPathAndFileName=src.client.ConfigClient.PATH_CLI_INCOMMING_BMP+incomingFileName;
}
//si c'est le WORKER qui recoit c'est pour avoir un pov
if (this.whoIam==src.utils.FileTransfer.ConfigFileSender.IAM_WORKER){
System.out.println("[SERVER] I'am a worker waiting for a .pov file");
this.outPutPathAndFileName=src.worker.ConfigWorker.PATH_POV_IN_WORKER+incomingFileName;
}
//si c'est le DISPATCHER qui recoit c'est pour avoir un .pov
if (this.whoIam==src.utils.FileTransfer.ConfigFileSender.IAM_DISPATCHER){
System.out.println("[SERVER] I'am a dispatcher waiting for a .pov file");
this.outPutPathAndFileName=src.dispatcher.ConfigDispatcher.PATH_DISP_POV_IN+incomingFileName;
}
/*
* Ouverture du socket pour recevoir le bytes du fichier
*/
socketListener = new ServerSocket(port);
System.out.println("[SERVER] socket created, listening on port for bytes >"+port);
System.out.println("[SERVER] Waiting for connection...");
socket = socketListener.accept();
System.out.println("[SERVER] Remote host has connect>"+(socket.getInetAddress()).toString());
long nbrSecDeb = java.lang.System.currentTimeMillis();
//Ouverture des flux et fichier d'output
this.openStreams();
nextByte = dataInputStream.read();//lit dans le socket le byte suivant
System.out.println("[SERVER] Started getting file");
while (nextByte != END_OF_FLUX){
dataOutputStream.write(nextByte);
//System.out.println("[Server] wrote > "+nextByte);
nextByte = dataInputStream.read();
}
this.closeStream();
//On ferme tous les flux, le socket, le fichier
long nbrSecEnd = java.lang.System.currentTimeMillis();
nbrSecEnd = nbrSecEnd-nbrSecDeb;
System.out.println("[SERVER] server has wait "+nbrSecEnd/1000 +" seconds with the transfert");
// Si c'est le DISPATCHER, il a recu un .pov
// Alors il ajoute la task au gestionnaire de task
if (this.whoIam==src.utils.FileTransfer.ConfigFileSender.IAM_DISPATCHER){
System.out.println("I'am dispatcher, i just received à pov file");
GestionnaireTask g = GestionnaireTask.getInstance();
g.addTask(incomingFileName);
}
//Si c'est le WORKER, il a recu un .pov donc il le traite
if (this.whoIam==src.utils.FileTransfer.ConfigFileSender.IAM_WORKER){
System.out.println("I'am worker, i just received à pov file");
// il retient qu'il vient de recevoir ce fichier là
src.worker.Worker.setLastFilePovFullyUploaded(incomingFileName);
// il le traite/renvoit au client/se notifie disponible
src.worker.Worker.traiterFragment(incomingFileName);
}
// Si c'est le CLIENT qui a recu un fichier c un bmp
// il doit marquer ce fragment comme recu dans sa taskList
// regarder si ce fragment est le dernier de la description!
if (this.whoIam==src.utils.FileTransfer.ConfigFileSender.IAM_CLIENT){
//il récupère la taskList
System.out.println("Récépration de la taskList du client");
TaskList2 t = TaskList2.getInstanceTaskList();
//il construit un objet fragement avec le ficheir recu
System.out.println(" Construit un objet fragment à partir du nom de fichier recu");
Fragment f = Fragment.makeFragmentObjectFromFILE(incomingFileName);
//nro de description du client
int idDescCli= f.getIdDesc();
//nro de fragment de la description
int nroFragDeDesc = f.getNroFrag();
t.addFragmentRecu(idDescCli, f.getNroFrag());
//Si c'était le dernier...
boolean isComplete = t.isComplete(idDescCli);
if (isComplete==true){
//on lance la recomposition d'iamge
System.out.println("Tous les fragments de la description nro>"+idDescCli + "ont été recu !");
//TODO LANCER RECOMPOSITION D'IMAGE!!
}
this.outPutPathAndFileName=src.client.ConfigClient.PATH_CLI_INCOMMING_BMP+incomingFileName;
}
}
catch(IOException io){
System.out.println("[Server] IOException "+io.getMessage());
System.out.println(this.port+" ne peut probablement pas être ouvert... (déjà bind)");
//TODO Robustesse, si ca pante qd il envoit le fichier...
}
}
public static void main(String[] args) {
try{
//Test 1 OK
//System.out.println("Je suis dispatcher j'attend le pov du client...");
//TCPServerFile2 t = new TCPServerFile2(55555,ConfigFileSender.IAM_DISPATCHER);
//TEST2 OK
//System.out.println("Je suis worker j'attend le pov du dispatcher...");
//TCPServerFile2 t = new TCPServerFile2(45678,ConfigFileSender.IAM_WORKER);
//TEST3 OK
System.out.println("Je suis client j'attend le BMP du worker...");
TCPServerFile2 t = new TCPServerFile2(45678,ConfigFileSender.IAM_CLIENT);
}
catch(Exception e){
e.printStackTrace();
}
}
} |