【问题标题】:Java, Socket : Send several object of an arrayList one by one, the objectInputStream does not read all of themJava, Socket : 一个一个地发送一个arrayList的几个对象,objectInputStream不会全部读取
【发布时间】:2016-06-06 22:39:54
【问题描述】:

大家好,在此先感谢阅读本文的人:

我正在尝试发送一个对象“配置文件”的 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 类(接受连接并启动客户端处理器线程,它只启动一个线程,所以现在用处不大,但以后会用):

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,但显然这不是问题的原因。 非常感谢您阅读了该内容,如果您可以运行此代码并告诉我您是否有同样的问题...

【问题讨论】:

    标签: java android sockets serialization deserialization


    【解决方案1】:

    问题出在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();
        }
    }   
    

    【讨论】:

      猜你喜欢
      • 2013-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-25
      • 1970-01-01
      • 1970-01-01
      • 2014-08-19
      • 2013-12-30
      相关资源
      最近更新 更多