OVH Cloud OVH Cloud

Socket : pb de fiabilité du transfert

8 réponses
Avatar
gart
Bonjour à tous.

J'essaye de faire une petite application pour envoyer, au travers
d'une socket, un fichier (zip). La connexion ainsi que le transfert ce
font correctement, et j'obtiens mon fichier sur le serveur.
Mon problème est qu'il est illisible (pb de CRC quand j'essaye de le
décompresser).

J'envoie d'abord une chaine de caractère contenant le nom du fichier.
Ensuite j'envoie le fichier lui-même.

Dans le serveur, je récupère le nom du fichier (pour le créer sur le
serveur) et ensuite je récupère le fichier.

Si quelqu'un a une piste, voir même une solution :p je suis preneur.

Voici les différentes classes utilisées :

Le client :

public class ClientTransfert {

protected int defautPort = 4253;
protected boolean connected = false;

protected Socket clSocket = null;
protected DataOutputStream os = null;
protected DataInputStream is = null;
/**
...
**/

public void send(String string, File file) {
send("SENDFILE:FILENAME:"+string+":");
send(file);
}

public void send(File fichier) {
FileReader fr;
try {
fr = new FileReader(fichier);
} catch (FileNotFoundException e) {
Trace.println("Error during opening of : "+fichier.getName());
e.printStackTrace();
return;
}
String ligne;
BufferedReader buffIn = new BufferedReader(fr);
try {
while(buffIn.ready() ) {
os.write(buffIn.read());
}
os.flush();
} catch (IOException e1) {
Trace.println("Error : error while reading from
"+fichier.getName()+" and writing to socket");
e1.printStackTrace();
return;
}
}

Et le serveur :

public class ServerTransfert {

protected int portEcouteDefaut = 4253;

protected ServerSocket socketEcoute = null;
/**
...
**/

private void gestionClient(Socket clSocket) {
int LVL = Trace.getLevel();
Trace.println(" ");

DataOutputStream cOutputStream = null;
InputStream cInputStream = null;
int len=0;

String command = new String("");
String temp;
System.out.println("Connection accepted from
"+clSocket.getInetAddress().toString()+" on port
"+clSocket.getPort());

try {
cOutputStream = new DataOutputStream(new
BufferedOutputStream(clSocket.getOutputStream()));
cInputStream = clSocket.getInputStream();
} catch (IOException e) {
Trace.println("Error : while creating DataStream from
clientSocket");
e.printStackTrace();
return;
}
char c = 0;
do {
try {
c = (char) cInputStream.read();
} catch (IOException e1) {
Trace.println("Error while reading from socket");
e1.printStackTrace();
return;
}
command = command+c;
if(command.equals("SENDFILE")) {
Trace.print("Recieving a FILE");
try {
cInputStream.read();
command = new String("");
} catch (IOException e2) {
Trace.println("Error while reading from the socket");
e2.printStackTrace();
return;
}
c = 0;
}
else if(command.equals("FILENAME")){
Trace.print(" with filename : ");
filename = new String("");
try {
cInputStream.read();
} catch (IOException e2) {
Trace.println("Error while reading from the socket");
e2.printStackTrace();
return;
}
try {
c = (char) cInputStream.read();
} catch (IOException e3) {
Trace.println("Error while reading from the socket");
e3.printStackTrace();
return;
}
while(c != ':') {
filename = filename+c;
try {
c = (char) cInputStream.read();
} catch (IOException e4) {
Trace.println("Error while reading from the socket");
e4.printStackTrace();
return;
}
Trace.print(""+c);
}
getFile(clSocket);
}
}while(c != ':');
try {
cOutputStream.close();
cInputStream.close();
} catch (IOException e1) {
Trace.println("Error while closing socket stream");
e1.printStackTrace();
}
}


/**
*
*/
private void getFile(Socket clSocket) {

int len = 0;
byte[] buffer = new byte[2000];

File fichier = new File(filename);
FileOutputStream fout = null;
BufferedOutputStream buffOut;
try {
fout = new FileOutputStream(fichier);
buffOut = new BufferedOutputStream(fout);
} catch (FileNotFoundException e1) {
Trace.println("Error, couldn't open file "+filename);
e1.printStackTrace();
return;
}
DataOutputStream cOutputStream = null;
InputStream cInputStream = null;
try {
cOutputStream = new DataOutputStream(new
BufferedOutputStream(clSocket.getOutputStream()));
cInputStream = clSocket.getInputStream();
} catch (IOException e) {
Trace.println("Error : while creating DataStream from
clientSocket");
e.printStackTrace();
return;
}
while(len != -1) {
try {
len = cInputStream.read(buffer);
if(len == -1) {
break;
}
} catch (IOException e2) {
Trace.println("Error while reading from socket");
e2.printStackTrace();
return;
}
try {
if(len == -1) {
break;
}
buffOut.write(buffer,0,len);
//Trace.println("writing file :"+new String(buffer,0,len));
} catch (IOException e3) {
Trace.println("Error while writing to file");
e3.printStackTrace();
return;
}
}
try {
buffOut.close();
fout.close();
Trace.println("File "+filename+" writed and closed");
} catch (IOException e2) {
Trace.println("Error while closing file : "+filename);
e2.printStackTrace();
}


}

D'avance merci,
Gart.

8 réponses

Avatar
garphy
compare les tailles de tes fichiers avant et apres transfert
j'ai pas lu super attentivement, mais tu pourrais, pour diagnostiquer,
ouvrir ton fichier reçu avec un editeur hexa et verifier qu'il ya pas une
chaine bizarre au début ou à la fin (un bout de commande de ton protocole)

Le Tue, 30 Sep 2003 06:59:07 -0700, Gart a écrit :

Bonjour à tous.

J'essaye de faire une petite application pour envoyer, au travers
d'une socket, un fichier (zip). La connexion ainsi que le transfert ce
font correctement, et j'obtiens mon fichier sur le serveur.
Mon problème est qu'il est illisible (pb de CRC quand j'essaye de le
décompresser).

J'envoie d'abord une chaine de caractère contenant le nom du fichier.
Ensuite j'envoie le fichier lui-même.

Dans le serveur, je récupère le nom du fichier (pour le créer sur le
serveur) et ensuite je récupère le fichier.

Si quelqu'un a une piste, voir même une solution :p je suis preneur.

Voici les différentes classes utilisées :

Le client :

public class ClientTransfert {

protected int defautPort = 4253;
protected boolean connected = false;

protected Socket clSocket = null;
protected DataOutputStream os = null;
protected DataInputStream is = null;
/**
...
**/

public void send(String string, File file) {
send("SENDFILE:FILENAME:"+string+":");
send(file);
}

public void send(File fichier) {
FileReader fr;
try {
fr = new FileReader(fichier);
} catch (FileNotFoundException e) {
Trace.println("Error during opening of : "+fichier.getName());
e.printStackTrace();
return;
}
String ligne;
BufferedReader buffIn = new BufferedReader(fr);
try {
while(buffIn.ready() ) {
os.write(buffIn.read());
}
os.flush();
} catch (IOException e1) {
Trace.println("Error : error while reading from
"+fichier.getName()+" and writing to socket");
e1.printStackTrace();
return;
}
}

Et le serveur :

public class ServerTransfert {

protected int portEcouteDefaut = 4253;

protected ServerSocket socketEcoute = null;
/**
...
**/

private void gestionClient(Socket clSocket) {
int LVL = Trace.getLevel();
Trace.println(" ");

DataOutputStream cOutputStream = null;
InputStream cInputStream = null;
int len=0;

String command = new String("");
String temp;
System.out.println("Connection accepted from
"+clSocket.getInetAddress().toString()+" on port
"+clSocket.getPort());

try {
cOutputStream = new DataOutputStream(new
BufferedOutputStream(clSocket.getOutputStream()));
cInputStream = clSocket.getInputStream();
} catch (IOException e) {
Trace.println("Error : while creating DataStream from
clientSocket");
e.printStackTrace();
return;
}
char c = 0;
do {
try {
c = (char) cInputStream.read();
} catch (IOException e1) {
Trace.println("Error while reading from socket");
e1.printStackTrace();
return;
}
command = command+c;
if(command.equals("SENDFILE")) {
Trace.print("Recieving a FILE");
try {
cInputStream.read();
command = new String("");
} catch (IOException e2) {
Trace.println("Error while reading from the socket");
e2.printStackTrace();
return;
}
c = 0;
}
else if(command.equals("FILENAME")){
Trace.print(" with filename : ");
filename = new String("");
try {
cInputStream.read();
} catch (IOException e2) {
Trace.println("Error while reading from the socket");
e2.printStackTrace();
return;
}
try {
c = (char) cInputStream.read();
} catch (IOException e3) {
Trace.println("Error while reading from the socket");
e3.printStackTrace();
return;
}
while(c != ':') {
filename = filename+c;
try {
c = (char) cInputStream.read();
} catch (IOException e4) {
Trace.println("Error while reading from the socket");
e4.printStackTrace();
return;
}
Trace.print(""+c);
}
getFile(clSocket);
}
}while(c != ':');
try {
cOutputStream.close();
cInputStream.close();
} catch (IOException e1) {
Trace.println("Error while closing socket stream");
e1.printStackTrace();
}
}


/**
*
*/
private void getFile(Socket clSocket) {

int len = 0;
byte[] buffer = new byte[2000];

File fichier = new File(filename);
FileOutputStream fout = null;
BufferedOutputStream buffOut;
try {
fout = new FileOutputStream(fichier);
buffOut = new BufferedOutputStream(fout);
} catch (FileNotFoundException e1) {
Trace.println("Error, couldn't open file "+filename);
e1.printStackTrace();
return;
}
DataOutputStream cOutputStream = null;
InputStream cInputStream = null;
try {
cOutputStream = new DataOutputStream(new
BufferedOutputStream(clSocket.getOutputStream()));
cInputStream = clSocket.getInputStream();
} catch (IOException e) {
Trace.println("Error : while creating DataStream from
clientSocket");
e.printStackTrace();
return;
}
while(len != -1) {
try {
len = cInputStream.read(buffer);
if(len == -1) {
break;
}
} catch (IOException e2) {
Trace.println("Error while reading from socket");
e2.printStackTrace();
return;
}
try {
if(len == -1) {
break;
}
buffOut.write(buffer,0,len);
//Trace.println("writing file :"+new String(buffer,0,len));
} catch (IOException e3) {
Trace.println("Error while writing to file");
e3.printStackTrace();
return;
}
}
try {
buffOut.close();
fout.close();
Trace.println("File "+filename+" writed and closed");
} catch (IOException e2) {
Trace.println("Error while closing file : "+filename);
e2.printStackTrace();
}


}

D'avance merci,
Gart.


Avatar
gart
"garphy" wrote in message news:...
compare les tailles de tes fichiers avant et apres transfert
j'ai pas lu super attentivement, mais tu pourrais, pour diagnostiquer,
ouvrir ton fichier reçu avec un editeur hexa et verifier qu'il ya pas une
chaine bizarre au début ou à la fin (un bout de commande de ton protocole)



Bonjour,

Pour la taille des fichiers, j'avais regardé et elles sont identiques.
En fait, je peux ouvrir le fichier obtenu (avec WinAce par exemple)
mais pas extraire les données. J'ai donc suivi votre conseil, et j'ai
éditer en hexa le fichier. Certaines différences sont apparues : des
éléments du fichiers ne sont pas identiques. Je penses donc qu'il y a
une sorte de "conversion" des données faites pendant leurs passage
dans le flux de la socket. Est-ce possible ? Et comment l'empecher ?

Si quelqu'un à une idée, je suis preneur,
D'avance merci,
Gart.

Avatar
Olivier Prin
J'ai survolé rapidement le programme et je me suis étonné de ne pas voir
de ByteArray ou ce genre de chose. J'ai pensé que ton pb serait peut
être du à l'utilisation d'un stream de type texte quelque part.

Je ne suis pas un pro du JDK donc je suis pas trop bien placé pour te
dire si un BufferedReader est utilisable pour lire des datas ou pas mais
à mon avis c'est quelque par dans les streams.

Olivier

Gart wrote:
"garphy" wrote in message news:...

compare les tailles de tes fichiers avant et apres transfert
j'ai pas lu super attentivement, mais tu pourrais, pour diagnostiquer,
ouvrir ton fichier reçu avec un editeur hexa et verifier qu'il ya pas une
chaine bizarre au début ou à la fin (un bout de commande de ton protocole)




Bonjour,

Pour la taille des fichiers, j'avais regardé et elles sont identiques.
En fait, je peux ouvrir le fichier obtenu (avec WinAce par exemple)
mais pas extraire les données. J'ai donc suivi votre conseil, et j'ai
éditer en hexa le fichier. Certaines différences sont apparues : des
éléments du fichiers ne sont pas identiques. Je penses donc qu'il y a
une sorte de "conversion" des données faites pendant leurs passage
dans le flux de la socket. Est-ce possible ? Et comment l'empecher ?

Si quelqu'un à une idée, je suis preneur,
D'avance merci,
Gart.



Avatar
jerome moliere
Gart wrote:
Bonjour à tous.

J'essaye de faire une petite application pour envoyer, au travers
d'une socket, un fichier (zip). La connexion ainsi que le transfert ce
font correctement, et j'obtiens mon fichier sur le serveur.
Mon problème est qu'il est illisible (pb de CRC quand j'essaye de le
décompresser).

J'envoie d'abord une chaine de caractère contenant le nom du fichier.
Ensuite j'envoie le fichier lui-même.

Dans le serveur, je récupère le nom du fichier (pour le créer sur le
serveur) et ensuite je récupère le fichier.

Si quelqu'un a une piste, voir même une solution :p je suis preneur.
quelqu'un t'as repondu sans meme que tu releves sa piste...

ton fichier est il du texte ou du binaire ?
si tu utilises du binaire, saches que le passage via un Reader va
transformer tes octets en caracteres encodes via l'encoding par defaut
sur ta VM..c'est donc une piste serieuse a creuser

Jerome

Avatar
steph
En effet, le BufferedReader est un objet permettant de lire des flux de
caractères et il y a donc une conversion entre le charset du fichier et celui de
la jvm.

Dans ton cas, il faut utiliser un BufferedInputStream qui gere un flux d'octets
sans conversion.



"garphy" wrote in message news:...

compare les tailles de tes fichiers avant et apres transfert
j'ai pas lu super attentivement, mais tu pourrais, pour diagnostiquer,
ouvrir ton fichier reçu avec un editeur hexa et verifier qu'il ya pas une
chaine bizarre au début ou à la fin (un bout de commande de ton protocole)




Bonjour,

Pour la taille des fichiers, j'avais regardé et elles sont identiques.
En fait, je peux ouvrir le fichier obtenu (avec WinAce par exemple)
mais pas extraire les données. J'ai donc suivi votre conseil, et j'ai
éditer en hexa le fichier. Certaines différences sont apparues : des
éléments du fichiers ne sont pas identiques. Je penses donc qu'il y a
une sorte de "conversion" des données faites pendant leurs passage
dans le flux de la socket. Est-ce possible ? Et comment l'empecher ?

Si quelqu'un à une idée, je suis preneur,
D'avance merci,
Gart.


--
stephane
retirez les lettres majuscules et le 666 de l'adresse pour l'utiliser.


Avatar
Nicolas Repiquet
"Gart" a écrit dans le message news:

Bonjour à tous.

J'essaye de faire une petite application pour envoyer, au travers
d'une socket, un fichier (zip). La connexion ainsi que le transfert ce
font correctement, et j'obtiens mon fichier sur le serveur.
Mon problème est qu'il est illisible (pb de CRC quand j'essaye de le
décompresser).

J'envoie d'abord une chaine de caractère contenant le nom du fichier.
Ensuite j'envoie le fichier lui-même.

Dans le serveur, je récupère le nom du fichier (pour le créer sur le
serveur) et ensuite je récupère le fichier.

Si quelqu'un a une piste, voir même une solution :p je suis preneur.


[snip]

public void send(File fichier) {
FileReader fr;
try {
fr = new FileReader(fichier);
} catch (FileNotFoundException e) {
Trace.println("Error during opening of : "+fichier.getName());
e.printStackTrace();
return;
}
String ligne;
BufferedReader buffIn = new BufferedReader(fr);
try {
while(buffIn.ready() ) {
os.write(buffIn.read());
}


Ouille.

C'est pas comme ça qu'on transfert un fichier binaire.
La notion de reader implique un décodage byte(s) => char, et ne n'est pas ce
que tu veut faire. Essayes plutot comme ça :

InputStream in = new FileInputStream(file);
byte[4096] buffer;
int count;
do {
count = in.read(buffer);
os.write(buffer,0,count);
} while( count == buffer.length );

Et pour la lecture :

OutputStream out = new FileOutputStream(file);
byte[4096] buffer;
int count;
do {
count = os.read(buffer);
out.write(buffer,0,count);
} while( count == buffer.length );


D'avance merci,
Gart.


De rien

-- Nicolas Repiquet

Avatar
gart
Ok, merci, je vais voir du côté d'autre type de stream, même si je
pense qu'un BufferedOutputStream travaile déjà sur des byte[], mais je
suis pas sur.
J'ai bien l'impression que je vais devoir faire autrement :/

Merci encore,
Gart.


Olivier Prin wrote in message news:<ble3ur$8cn$...
J'ai survolé rapidement le programme et je me suis étonné de ne pas voir
de ByteArray ou ce genre de chose. J'ai pensé que ton pb serait peut
être du à l'utilisation d'un stream de type texte quelque part.

Je ne suis pas un pro du JDK donc je suis pas trop bien placé pour te
dire si un BufferedReader est utilisable pour lire des datas ou pas mais
à mon avis c'est quelque par dans les streams.

Olivier

Gart wrote:
"garphy" wrote in message news:...

compare les tailles de tes fichiers avant et apres transfert
j'ai pas lu super attentivement, mais tu pourrais, pour diagnostiquer,
ouvrir ton fichier reçu avec un editeur hexa et verifier qu'il ya pas une
chaine bizarre au début ou à la fin (un bout de commande de ton protocole)




Bonjour,

Pour la taille des fichiers, j'avais regardé et elles sont identiques.
En fait, je peux ouvrir le fichier obtenu (avec WinAce par exemple)
mais pas extraire les données. J'ai donc suivi votre conseil, et j'ai
éditer en hexa le fichier. Certaines différences sont apparues : des
éléments du fichiers ne sont pas identiques. Je penses donc qu'il y a
une sorte de "conversion" des données faites pendant leurs passage
dans le flux de la socket. Est-ce possible ? Et comment l'empecher ?

Si quelqu'un à une idée, je suis preneur,
D'avance merci,
Gart.





Avatar
gart
Bonjour,
Effectivement, j'avais commencé à soupçonné un truc comme cela, mais
je m'y perdais un peu dans tout ces streams, désolé :)
J'ai résolu le problème, tout ce passe bien maintenant.
Merci à tous.
Gart.

"Nicolas Repiquet" wrote in message news:<3f7abd1e$0$27024$...
[snip]

public void send(File fichier) {
FileReader fr;
try {
fr = new FileReader(fichier);
} catch (FileNotFoundException e) {
Trace.println("Error during opening of : "+fichier.getName());
e.printStackTrace();
return;
}
String ligne;
BufferedReader buffIn = new BufferedReader(fr);
try {
while(buffIn.ready() ) {
os.write(buffIn.read());
}


Ouille.

C'est pas comme ça qu'on transfert un fichier binaire.
La notion de reader implique un décodage byte(s) => char, et ne n'est pas ce
que tu veut faire. Essayes plutot comme ça :

InputStream in = new FileInputStream(file);
byte[4096] buffer;
int count;
do {
count = in.read(buffer);
os.write(buffer,0,count);
} while( count == buffer.length );

Et pour la lecture :

OutputStream out = new FileOutputStream(file);
byte[4096] buffer;
int count;
do {
count = os.read(buffer);
out.write(buffer,0,count);
} while( count == buffer.length );


D'avance merci,
Gart.


De rien

-- Nicolas Repiquet