如何通过Socket与ObjectOutputStream实现Java服务器向Android客户端传输Etudient对象
Java Socket 传输 Etudient 对象的问题分析与修复方案
你的这段服务器端代码存在几个关键问题,会直接导致对象传输失败,咱们一步步拆解并修复:
核心问题梳理
- 过早关闭输出流与Socket:你在
while循环内部每次写完一个对象就调用out.close(),这会立刻关闭ObjectOutputStream,同时底层的Socket连接也会被强制关闭。循环的第一次迭代结束后,连接就断了,后续的etudtoandroid对象根本发不出去,客户端还会因为连接意外中断抛出IO异常。 - 未确保类可序列化:你的
etudtoandroid类必须实现java.io.Serializable接口,否则ObjectOutputStream无法将对象序列化为字节流。如果没实现,发送时会直接抛出NotSerializableException。
修复步骤与代码示例
1. 确保etudtoandroid类实现Serializable接口
这是对象序列化传输的前提,建议显式声明序列化版本UID,避免类结构变化导致反序列化兼容性问题:
import java.io.Serializable; public class etudtoandroid implements Serializable { // 显式声明序列化版本UID private static final long serialVersionUID = 1L; private String matricule; private String nom; private String prenom; // 构造方法 public etudtoandroid(String matricule, String nom, String prenom) { this.matricule = matricule; this.nom = nom; this.prenom = prenom; } // 可选:添加getter方法方便客户端读取字段 public String getMatricule() { return matricule; } public String getNom() { return nom; } public String getPrenom() { return prenom; } }
2. 修正服务器端发送逻辑
把out.close()和clientSocket.close()移到循环外部,确保所有对象都发送完成后再关闭流和连接:
try { // 假设已完成Socket、ObjectOutputStream、ResultSet的初始化 List<etudtoandroid> userliste = new ArrayList<>(); while(rt.next()){ etudtoandroid us1 = new etudtoandroid( rt.getString("matricule"), rt.getString("nom"), rt.getString("prenom") ); System.out.println("object remplie"); out.writeObject(us1); out.flush(); // 可选,若需要立即推送数据可保留 userliste.add(us1); System.out.println("object envoye"); } // 所有对象发送完毕后,再关闭资源 out.close(); clientSocket.close(); rt.close(); // 别忘了关闭ResultSet } catch (IOException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); }
3. 客户端对应读取逻辑(Android端)
客户端需要用ObjectInputStream读取对象,建议通过约定的结束标记(比如服务器发送null)来判断传输结束:
try { Socket socket = new Socket("服务器IP地址", 端口号); ObjectInputStream in = new ObjectInputStream(socket.getInputStream()); etudtoandroid etudiant; // 循环读取直到收到null(服务器发送完所有对象后需写入null) while ((etudiant = (etudtoandroid) in.readObject()) != null) { // 处理收到的学生对象 Log.d("Client", "收到学生:" + etudiant.getNom() + " " + etudiant.getPrenom()); } // 关闭资源 in.close(); socket.close(); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); }
优化建议
- 批量传输更高效:如果需要传输多个对象,直接把整个
userliste列表一次性发送会更高效,减少IO操作:
服务器端:out.writeObject(userliste);
客户端:List<etudtoandroid> studentList = (List<etudtoandroid>) in.readObject(); - 保持类结构一致:服务器和客户端的
etudtoandroid类必须完全一致(包名、类名、字段名/类型都要相同),否则反序列化会失败。
内容的提问来源于stack exchange,提问作者Derrar A Rahim
相关产品推荐
相关产品推荐

