Les sockets mangent les bytes !

Fermé
TheKill_TnT Messages postés 148 Date d'inscription lundi 15 mai 2017 Statut Membre Dernière intervention 22 juin 2019 - 17 avril 2019 à 20:39
TheKill_TnT Messages postés 148 Date d'inscription lundi 15 mai 2017 Statut Membre Dernière intervention 22 juin 2019 - 19 avril 2019 à 14:31
Bonjour, j'expérimente un code d'envoie de fichier Client <-> Serveur via la mise en byte du contenu des fichiers.
En soi, tout fonctionne normalement, mais si on a l’œil et qu'on ouvre le fichier on se rend compte de la bétise...
Mais, laquelle ?
Voilà... Le début du fichier a été mangé par java -_-
Par exemple:
Fichier txt: egzeroirbego -> oirbego
Fichier mp3: Durée 5 secondes -> Durée 4 secondes (environ 1 seconde est mangée)
Fichier image: Beau koala de la part de windows -> Image de fichier incorrect

Bref, autant le texte je peut le parer en ajoutant du texte inutile au début, autant le son il me faut rajouter un blanc au début, autant l'image va savoir comment je peux palier au problème :/

Evidemment je n'allais quand même pas vous laisser sans le code, vous ne pourriez faire grand chose...

JavaTest.java (Classe principale Client)
package javatest;

import sun.net.www.protocol.http.HttpURLConnection;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.Socket;
import java.net.URL;


public class JavaTest {


    public static void main(String[] args){


        System.out.println("Starting !");
        PrintStream realout = System.out;

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setLocationRelativeTo(null);
        frame.setSize(800,800);

        JTextArea jta = new JTextArea();
        jta.setEditable(false);
        jta.setBounds(10,10, 760, 760);
        jta.setRows(50);
        jta.setColumns(50);

        BackPane bp = new BackPane();
        bp.setLayout(null);
        bp.add(jta);
        frame.setContentPane(bp);

        System.setOut(new PrintStream(new Output(jta)));

        System.out.println("Debug initialized !");
        realout.println("Euh...");
        File f = new File("files");
        if(!f.exists())f.mkdir();
        System.out.println("Looking for the server...");
        Socket client = null;
        try {
            client = new Socket("localhost", 25565);
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("Unable to find server. Stopping !");
            JButton leave = new JButton("Erreure ! Quitter...");
            leave.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                System.exit(0);
                }
            });
            leave.setBounds(50,50,300,100);
            bp.add(leave);
            return;
        }
        System.out.println("Launching...");
        System.out.println("Searching files for transfer...");
        for(File fi : f.listFiles()){

            System.out.println("Starting transfer of "+fi.getName()+"...");
            try {
                PrintWriter ws = new PrintWriter(client.getOutputStream());
                DataOutputStream dos = new DataOutputStream(client.getOutputStream());

                FileInputStream fis = new FileInputStream(fi);
                ws.println("Transfert of "+fi.getName()+"...");
                ws.flush();
                ws.println("[[[FILE]]] "+fi.getName());
                ws.flush();
                byte buf[] = new byte[1024];
                int n = 0;
                while((n=fis.read(buf))!=-1) {
                    dos.write(buf, 0, n);
                    Thread.sleep(20);
                }
                System.out.println("Finished transfer of " + fi.getName() + " !");
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("Error while transfer of "+fi.getName()+".");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            try {
                Thread.sleep(31000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }

    }


}


Le serveur (JavaTestServer.java):
package javatest;

import javax.swing.*;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Time;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;

public class JavaTestServer {
    private static boolean run = false;
    private static int clientid = 0;
    private static Output op;
    public static void main(String[] args){

        System.out.println("Starting !");
        PrintStream realout = System.out;

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setLocationRelativeTo(null);
        frame.setSize(800,800);

        JTextArea jta = new JTextArea();
        jta.setEditable(false);
        jta.setBounds(10,10, 760, 760);
        jta.setRows(50);
        jta.setColumns(50);

        BackPane bp = new BackPane();
        bp.setLayout(null);
        bp.add(jta);
        frame.setContentPane(bp);

        op = new Output(jta);
        System.setOut(new PrintStream(op));

        System.out.println("Debug initialized !");

        try {
            ServerSocket ss = new ServerSocket(25565);


            System.out.println("Loaded server (port 25565) !");
            run = true;
            new Thread(()->{
                System.out.println("[System] System initialized ! [End]");
                while(run){


                    Socket client = null;
                    try {
                        client = ss.accept();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    Socket finalClient = client;
                    new Thread(()->{
                        int id = 0;
                        try {
                            PrintWriter out = new PrintWriter(finalClient.getOutputStream());
                            BufferedReader in = new BufferedReader(new InputStreamReader(finalClient.getInputStream()));

                            id= ++clientid;
                            System.out.println("[Client "+id+"] Connected ! [End]");


                            while(run){

                                String msg = in.readLine();
                                if(msg.startsWith("[[[FILE]]]")){
                                    DataInputStream dis = new DataInputStream(finalClient.getInputStream());
                                    String filename = msg.replace("[[[FILE]]] ", "");
                                    File f = new File("downloads/"+filename);
                                    if(!f.exists())f.createNewFile();
                                    realout.println("Received 1");
                                    System.out.println("[System] Received file \""+filename+"\" from client "+id+", beginning transfer... [End]");
                                    FileOutputStream fos = new FileOutputStream(f);
                                    byte buf[] = new byte[1024];
                                    int n;
                                    while((n=dis.read(buf))!=-1){
                                        fos.write(buf,0,n);
                                    }

                                    realout.println("Finish 1");
                                    System.out.println("[System] Finished file \""+filename+"\" transfer ! [End]");
                                    in = new BufferedReader(new InputStreamReader(finalClient.getInputStream()));
                                }else {
                                    op.println("[Client " + id + "] " + msg + " [End]");
                                }

                            }


                        } catch (IOException e) {
                            if(e.getMessage().equalsIgnoreCase("Connection reset")){

                                System.out.println("[System] Client "+id+" have lost connection. [End]");


                            }
                            e.printStackTrace();
                        }


                        }).start();




                }

            }).start();
















        } catch (IOException e) {
            e.printStackTrace();
        }


    }
}



A noter:
La classe "Output" est une classe qui redirige System.out vers la JTextArea d'une fenêtre.
Chaque classe est principale car j'ai eu la flemme de séparer les projets en deux, mais à aucun moment les deux n'utilisent le même dossier et ils ne s'appellent pas (pas d'invocation ou quoi)

1 réponse

tarek_dotzero Messages postés 817 Date d'inscription jeudi 19 juillet 2007 Statut Membre Dernière intervention 12 avril 2022 120
19 avril 2019 à 00:16
Bonjour,

Je ne suis sûre mais il y a une piste à suivre : vous créez les deux objets PrintWriter (ws) et DataOutputStream (dos) à partir du même stream qui est celui de la socket client. Je me demande est ce que cela ne pose pas de problème lors de l'envoie des données ?
0
TheKill_TnT Messages postés 148 Date d'inscription lundi 15 mai 2017 Statut Membre Dernière intervention 22 juin 2019 32
19 avril 2019 à 14:31
A priori non. Les données sont envoyées par TCP, si elles ne sont pas correctement reçues elles sont renvoyées automatiquement. Donc si l'envoi échouais complètement, celà mettrais plus de temps à arriver et Java lèverais une exception, ce qui n'est pas le cas.
Je pense que les bytes sont soit bouffées à l'arrivée (stream pas encore initialisé) soit au départ, à la lecture.
0