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...