1

Hello everybody and thanks in advance to those who will read that :

I'm trying to send an ArrayList of an object "Profile" (which I made serializable) but one by one (because at the end the List will be filled by other threads but this is not the matter here). I'm using a socket between a "clientconnexion" (which is the client) and a "clientprocessor" (which is the server). They are in different threads and at the end they will be on different computers.

When I try to do it with the following code (trying to send 50 profiles) I do receive some of them (like the 20 first, or the 30 first, sometimes even all of them or none...) but the clientconnexion stops receiving the profiles at one time...

Here is the code :

The class Profile :

public class Profile implements Serializable {

private static final long serialVersionUID = 2406276545874892098L;
public int id;
public String name;

public Profile(String name, int id){
    this.id=id;
    this.name=name;
}

}

The class Server (which accept the connexion and start clientprocessor thread, it only start one thread so it isn't really usefull now but it will be after) :

public class serveur {

private int port;
private String host = "0.0.0.0";
private ServerSocket server = null;
private boolean isRunning = true;

public serveur(String pHost, int pPort){
   host = pHost;
   port = pPort;
   try {
      server = new ServerSocket(port, 100, InetAddress.getByName(host));
   } catch (UnknownHostException e) {
      e.printStackTrace(); 
   } catch (IOException e) {
      e.printStackTrace();
   }
}

public void open(){
   Thread t = new Thread(new Runnable(){
      public void run(){
         while(isRunning == true){

            try {
               Socket client = server.accept();
               client.setTcpNoDelay(true);                 
               Thread t = new Thread(new clientprocessor(client));
               t.start();   
            } catch (IOException e) {
               e.printStackTrace();
            }
         }

         try {
            server.close();
         } catch (IOException e) {
            e.printStackTrace();
            server = null;
         }
      }
   });
   t.start();
}

public void close(){
   isRunning = false;
}   

}

The class clientprocessor :

public class clientprocessor implements Runnable {

private Socket client;
private BufferedOutputStream bos=null;
private BufferedInputStream bis=null;
private BufferedWriter writer=null;
private BufferedReader reader=null;
private ArrayList<Profile> profilesToSend;

public clientprocessor (Socket client){
    this.client = client;
    this.profilesToSend=new ArrayList<>();
    for (int i=1; i<51; i++){
        this.profilesToSend.add(new Profile("test", i));
    }
}

public synchronized Profile getProfile () {
    Iterator<Profile> itr = this.profilesToSend.iterator();
    if (itr.hasNext()){
        Profile P = itr.next();
        itr.remove();
        return P;
    }
    return null;
}

public void run (){
    try {
        bos= new BufferedOutputStream (client.getOutputStream());
        bis= new BufferedInputStream (client.getInputStream());
        writer=new BufferedWriter(new OutputStreamWriter(bos));
        reader=new BufferedReader(new InputStreamReader(bis));

        ObjectOutputStream oos=new ObjectOutputStream(bos);
        Profile P;

        while ((P = this.getProfile())!=null) {
            writer.write(0);   //when the client receive a zero, e knows he will receive a profile
            writer.flush();
            oos.writeObject(P);
            oos.flush();
            System.out.println("clientprocessor : profile written (" + P.name + " " +P.id +")");
            int i=reader.read(); //Waiting to receive a one to be sure that the object was received
            System.out.println("clientprocessor : integer received : " +i);
        }

        System.out.println("--------clientprocessor : all profiles sent--------");
        writer.write(1);   //when the client receive a one he knows he will not receive profiles anymore
        writer.flush();
    }  catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            writer.close();
            reader.close();
            bis.close();
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

}

The class clientconnexion (which is supposed to be on another computer at the end) :

public class clientconnexion implements Runnable {

private Socket connexion;
private BufferedOutputStream bos=null;
private BufferedInputStream bis=null;
private BufferedWriter writer=null;
private BufferedReader reader=null;

public clientconnexion(String adress, int port) {
    try {
         connexion = new Socket(adress, port);
      } catch (UnknownHostException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
}

@Override
public void run() {
    try {
        connexion.setTcpNoDelay(true);
        bos= new BufferedOutputStream (connexion.getOutputStream());
        bis= new BufferedInputStream (connexion.getInputStream());
        writer=new BufferedWriter(new OutputStreamWriter(bos));
        reader=new BufferedReader(new InputStreamReader(bis));
        ObjectInputStream ois = new ObjectInputStream(bis);
        int k = reader.read();
        String S="clientconnexion  : profiles received : ";
        while (k==0){
            System.out.println("clientconnexion : waiting for an object to read");
            Profile P=(Profile)ois.readObject();
            S = S + P.name + " " + P.id+ " ; ";
            System.out.println(S);
            writer.write(1);//the client sends a 1 to the server (clientprocessor)
            writer.flush();
            k=reader.read();
        }
    } catch (IOException e) {
        System.out.println(e);
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } finally {
        try {
            bis.close();bos.close();reader.close();writer.close();
            System.out.println("clientconnexion : streams closed");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }   
}

}

And finally the class test which is launching all that :

public class test {

public static String adresse = "localhost";
public static int port = 9028;

public static void main(String[] args) {

      serveur serveur = new serveur ("0.0.0.0",port);
      System.out.println("--Test : serveur créé"); 
      serveur.open();
      System.out.println("Test : serveur ouvert");

      Thread tclient1= new Thread(new clientconnexion(adresse, port));tclient1.start();

}

As you can see I tried to setTCPnoDelay but obviously it wasn't the reason of the problem. Thanks a lot if you read that and if you can run this code and tell me if you have the same problems...

1 Answer 1

1

The problem is in clientprocessor class both ObjectOutputStream and BufferedWriter cannot connect to the same stream. Likewise in clientconnexion class both ObjectInputStream and BufferedReader cannot connect to the same stream. The following changes should work

clientprocessor class

try {
    bos= new BufferedOutputStream (client.getOutputStream());
    bis= new BufferedInputStream (client.getInputStream());
    //writer=new BufferedWriter(new OutputStreamWriter(bos));
    reader=new BufferedReader(new InputStreamReader(bis));

    ObjectOutputStream oos=new ObjectOutputStream(bos);
    Profile P;

    while ((P = this.getProfile())!=null) {

        //writer.write(0);   //when the client receive a zero, e knows he will receive a profile
        //writer.flush();
        oos.write(0);
        oos.flush();
        oos.writeObject(P);
        oos.flush();
        System.out.println("clientprocessor : profile written (" + P.name + " " +P.id +")");
        int i=reader.read(); //Waiting to receive a one to be sure that the object was received
        System.out.println("clientprocessor : integer received : " +i);
    }

    System.out.println("--------clientprocessor : all profiles sent--------");
    //writer.write(1);   //when the client receive a one he knows he will not receive profiles anymore
    //writer.flush();
    oos.write(1);
    oos.flush();
}  catch (IOException e) {
    e.printStackTrace();
} finally {
    try {
        //writer.close();
        reader.close();
        bis.close();
        bos.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

clientconnexion class

try {
    connexion.setTcpNoDelay(true);
    bos= new BufferedOutputStream (connexion.getOutputStream());
    bis= new BufferedInputStream (connexion.getInputStream());
    writer=new BufferedWriter(new OutputStreamWriter(bos));
    //reader=new BufferedReader(new InputStreamReader(bis));
    ObjectInputStream ois = new ObjectInputStream(bis);
    int k = ois.read();
    String S="clientconnexion  : profiles received : ";
    while (k==0){
        System.out.println("clientconnexion : waiting for an object to read");
        Profile P=(Profile)ois.readObject();
        S = S + P.name + " " + P.id+ " ; ";
        System.out.println(S);
        writer.write(1);//the client sends a 1 to the server (clientprocessor)
        writer.flush();
        k=ois.read();
    }
} catch (IOException e) {
    System.out.println(e);
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} finally {
    try {
        bis.close();
        bos.close();
        //reader.close();
        writer.close();
        System.out.println("clientconnexion : streams closed");
    } catch (IOException e) {
        e.printStackTrace();
    }
}   
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.