大家好,在此先感谢那些阅读以下内容的人:

我正在尝试发送对象“配置文件”的ArrayList(我使它可序列化),但要一个接一个地发送(因为列表的末尾将被其他线程填充,但这不是问题)。
我在“clientconnexion”(即客户端)和“clientprocessor”(即服务器)之间使用套接字。它们位于不同的线程中,最后它们将位于不同的计算机上。

当我尝试使用以下代码(尝试发送50个配置文件)时,我确实收到了其中一些(例如前20个,或前30个,有时甚至全部或全部都没有...),但clientconnexion停止接收一次查看个人资料...

这是代码:

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;
}

}

Server(接受连接并启动clientprocessor线程,它仅启动一个线程,因此它现在并不是真正有用,但它将在之后):
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;
}

}

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();
        }
    }
}

}

clientconnexion(应该在末尾的另一台计算机上):
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();
        }
    }
}

}

最后是test类,它将启动所有这些:
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();

}

如您所见,我尝试使用setTCPnoDelay,但显然这不是问题的原因。
非常感谢您阅读并能运行此代码并告诉我是否存在相同的问题...

最佳答案

问题在于clientprocessor类中,ObjectOutputStreamBufferedWriter无法连接到同一流。同样,在clientconnexion类中,ObjectInputStreamBufferedReader都无法连接到同一流。以下更改应该起作用
clientprocessor

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
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();
    }
}

09-08 03:32