【问题标题】:issue in reading a serialized object读取序列化对象的问题
【发布时间】:2014-04-07 21:01:06
【问题描述】:

我正在尝试创建一个客户端-服务器 android 应用程序,我想在其中使用 UDP 协议传输文件。到目前为止,我能够传输文件并接收数据包的确认。

现在我想将序列号添加到数据包中的数据中。我已尝试执行以下操作:

  • 创建一个 ByteArrayOutputStream。
  • 将其包装在 ObjectOutputStream 中
  • 使用writeObject()向对象写入数据

序列化类包括:

public class Message implements Serializable {

private int seqNo;
private byte[] data;
private boolean ack;

public Message(int seqNo, byte[] data, boolean ack) {
    this.seqNo = seqNo;
    this.data = data;
    this.ack = ack;
}

客户端

byte[] fileBytes = new byte[500];
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(outStream);

while((numBytesRead = inputBuf.read(fileBytes)) != -1) {
//DatagramPacket packet = new DatagramPacket(fileBytes, fileBytes.length);
if (os == null) {
    os = new ObjectOutputStream(outStream);
}
        Message msg = new Message(++seqNo, fileBytes, false);   
    os.writeObject(msg);
    os.flush();
    os.reset();

    byte[] data = outStream.toByteArray();
    atagramPacket packet = new DatagramPacket(data, data.length);
    clientSocket.send(packet);
    }

服务器端

byte[] incomingData = new byte[1024];
while (true) {
try{
    DatagramPacket incomingPacket = new DatagramPacket(incomingData, incomingData.length);                                                      
        serverSocket.receive(incomingPacket);
    byte[] data = incomingPacket.getData();                 
    ByteArrayInputStream in = new ByteArrayInputStream(data);                             
        ObjectInputStream is = new ObjectInputStream(in);

    if (is == null) {
           is = new ObjectInputStream(in);
    }
    Message msg = (Message) is.readObject();
    System.out.println(msg.getSeqNo());
    out.write(msg.getData(),0,msg.getData().length);
      }

我面临的问题是

  1. 我收到的每个数据包的序列号相同(即 1)
  2. 我不确定传入数据包的缓冲区大小,因为我在客户端使用 500 字节,在
    使用 1024 服务器。如果我在两边都取 500 个字节,我会得到一个 EOFexception。

如果您能提出更好的方法来实现同样的事情,我将不胜感激!谢谢:)

【问题讨论】:

    标签: android serialization udp


    【解决方案1】:

    Message msg = new Message(++seqNo, fileBytes, false);

    在这里,您假设先前的 read() 已填满缓冲区。在文件结尾之前的最后一次 read() 中,它几乎肯定不会,并且不保证任何时候都会填充它,只传输至少一个字节。

    您应该将读取计数“numBytes”传递给此构造函数,它应该创建一个该大小的字节数组,并且只将那么多字节复制到其中。

    其他问题:

    • 在您测试时,“os”不可能为空。
    • 同上“是”。
    • 您应该为每个数据报创建一个新的 ObjectOutputStream 和 ByteArrayOutputStream。
    • Java 数据报不断缩小到目前收到的最短数据报有效负载的大小。您必须为每次接收创建一个新的,或者至少在每次接收之前重置其长度。
    • 由于 ObjectOutputStream 开销,您需要在接收器处使用更大的缓冲区。
    • 我不相信这段代码目前根本不能工作,更不用说你总是得到相同的序列号。您更有可能一直收到相同的消息,,因为您忽略了某处的异常。

    【讨论】:

    • 感谢 EJP 的回复。你能帮我理解“你应该将读取计数'numBytes'传递给这个构造函数,它应该创建一个该大小的字节数组,并且只复制那么多字节。”
    • 我不明白为什么它是必要的。我希望任何称职的程序员都能够直接根据该规范进行编码。一次拿一块。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-08
    • 1970-01-01
    • 2010-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多