You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:58:19