Java,Socket : Send several object of an arrayList one by one, objectInputStream 没有全部读取

标签 java android sockets serialization deserialization

大家好,提前感谢那些会阅读这篇文章的人:

我正在尝试发送一个对象“Profile”(我已将其序列化)的 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 但显然这不是问题的原因。 非常感谢,如果你阅读了这篇文章,如果你能运行这段代码并告诉我你是否有同样的问题...

最佳答案

问题出在 clientprocessor 类中,ObjectOutputStreamBufferedWriter 无法连接到同一个流。同样,在 clientconnexion 类中,ObjectInputStreamBufferedReader 都不能连接到同一个流。以下更改应该有效

客户端处理器

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

关于Java,Socket : Send several object of an arrayList one by one, objectInputStream 没有全部读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35605566/

相关文章:

java - 如何在另一个 servlet 的 init() 方法中使用一个 servlet 的输出?

java - Spring:获取 FactoryBean 对象而不是 FactoryBean.getObject()

java - android.database.sqlite.SQLiteException : no such table: yoga (code 1 SQLITE_ERROR):

delphi - 阻塞套接字会触发哪些事件?

在 Maven 构建生命周期中集成最好的 JavaScript 测试

Java健康检查最佳实践

javascript - 将 es6-promise polyfill 导入 Vue.js

java - 内存使用率高且同一进程显示多次?

c++ - NTP 服务器返回始终相同 - 错误的日期 (windows)

c++ - 在 C++ 中将数据添加到 struct addrinfo