0

这是一个任务,我正在尝试几种不同的方法来处理:

我们已经使用 UDP 来模拟 TCP。今天早些时候,我设法让文件传输通过 UDP 工作,但当然我没有检查重新发送“段”的错误,所以我没有尝试实现一个带有 ID 和一些字节数据的消息类型类。

调试显示我正确地制作了我的消息对象,然后我使用 public byte[]serialize(Object obj)将我的对象转换为用于 UDP 数据报传输的字节数组。

在接收端,当我将反序列化的对象转换回消息时,它崩溃了。

铸造失败

Message receiveMSG = null;
    try {
        receiveMSG = (Message)deserialize(receivedPacket.getData());
    } catch (ClassNotFoundException ex) {
        Logger.getLogger(UDPReceiver.class.getName()).log(Level.SEVERE, null, ex);
    }

反序列化方法

private Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
        ByteArrayInputStream b = new ByteArrayInputStream(bytes);
        ObjectInputStream o = new ObjectInputStream(b);
        return (Message)o.readObject();
    }

任何人都可以发现为什么这个演员会失败?谢谢你。

消息类

public class Message implements Serializable {

    private int segmentID;
    private byte[] packet;

    public Message(int segmentID, byte[] packet)
    {
        this.segmentID = segmentID;
        this.packet = packet;
    }

    public int getSegmentID()
    {
        return segmentID;
    }

    public byte[] getPacket()
    {
        return packet;
    }
}

UDPSENDER 类

public class UDPSender implements Sender{
    private File theFile;
    private FileInputStream fileReader;
    private DatagramSocket datagramSocket;
    private int fileLength, currentPos, bytesRead, toPort;
    private byte[]  msg, buffer;
    private String toHost,initReply;
    private InetAddress toAddress;
    private int segmentID;

    public UDPSender(InetAddress address, int port) throws IOException{
    toPort = port;
    toAddress = address;
    msg = new byte[512];
    buffer = new byte[512];
    datagramSocket = new DatagramSocket();
        datagramSocket.connect(toAddress, toPort);
        segmentID = 0;
    }

    @Override
    public void sendFile(File theFile) throws IOException{
    // Init stuff
    fileReader = new FileInputStream(theFile);
    fileLength = fileReader.available();

    System.out.println(" -- Filename: "+theFile.getName());
    System.out.println(" -- Bytes to send: "+fileLength);

    send((theFile.getName()+"::"+fileLength).getBytes());

    DatagramPacket reply = new DatagramPacket(buffer, buffer.length);
    datagramSocket.receive(reply);

    if (new String(reply.getData(), 0, reply.getLength()).equals("OK"))
        {
        System.out.println("  -- Got OK from receiver - sending the file ");
        int length;
        while (currentPos<fileLength){

            bytesRead = fileReader.read(msg);

            Message message = new Message(1,msg);

            send(serialize(message));

            currentPos = currentPos + bytesRead;
        }
        System.out.println("  -- File transfer complete...");
        }
    else{System.out.println("Recieved something other than OK... exiting");}
    }

    private void send(byte[] message, int length) throws IOException {
    DatagramPacket packet = 
            new DatagramPacket(message, length);
    datagramSocket.send(packet);
    }   

    private void send(byte[] message) throws IOException {
    DatagramPacket packet = 
            new DatagramPacket(message, message.length);
    datagramSocket.send(packet);
    }

    public byte[] serialize(Object obj) throws IOException {
        ByteArrayOutputStream b = new ByteArrayOutputStream();
        ObjectOutputStream o = new ObjectOutputStream(b);
        o.writeObject(obj);
        return b.toByteArray();
    }
}

UDP接收器

public class UDPReceiver {

    DatagramSocket socket;
    String filename, initString;
    byte[] buffer;
    DatagramPacket initPacket, receivedPacket;
    FileOutputStream fileWriter;
    int bytesReceived, bytesToReceive;

    public UDPReceiver(int port) throws IOException {
        // Init stuff
        socket = new DatagramSocket(port);
        buffer = new byte[516];

        System.out.println(" -- Ready to receive file on port: " + port);

        initPacket = receivePacket();

        initString = "Recieved-" + new String(initPacket.getData(), 0, initPacket.getLength());
        StringTokenizer t = new StringTokenizer(initString, "::");
        filename = t.nextToken();
        bytesToReceive = new Integer(t.nextToken()).intValue();

        System.out.println("  -- The file will be saved as: " + filename);
        System.out.println("  -- Expecting to receive: " + bytesToReceive + " bytes");

        send(initPacket.getAddress(), initPacket.getPort(), (new String("OK")).getBytes());

        fileWriter = new FileOutputStream(filename);

        while (bytesReceived < bytesToReceive) {
            receivedPacket = receivePacket();
            Message receiveMSG = null;
            try {
                receiveMSG = (Message)deserialize(receivedPacket.getData());
            } catch (ClassNotFoundException ex) {
                Logger.getLogger(UDPReceiver.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.out.println(receiveMSG.getSegmentID());

//            System.out.println(bytesReceived);
//            send(initPacket.getAddress(), initPacket.getPort(), (new String("OK")).getBytes());
        }
        System.out.println("  -- File transfer complete.");
    }

    public DatagramPacket receivePacket() throws IOException {

        DatagramPacket packet =
                new DatagramPacket(buffer, buffer.length);
        socket.receive(packet);

        return packet;
    }

    public byte[] receiveData() throws IOException {

        DatagramPacket packet =
                new DatagramPacket(buffer, buffer.length);
        socket.receive(packet);

        return packet.getData();
    }

    public void send(InetAddress recv, int port, byte[] message)
            throws IOException {

        DatagramPacket packet =
                new DatagramPacket(message, message.length, recv, port);
        socket.send(packet);
    }

    private Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
        ByteArrayInputStream b = new ByteArrayInputStream(bytes);
        ObjectInputStream o = new ObjectInputStream(b);
        return (Message)o.readObject();
    }
}
4

1 回答 1

0

好的,我终于调试了演员阵容失败的原因。

我没有考虑序列化对象的完整字节大小。我将接收缓冲区更改为 607 字节,并且转换工作正常。

于 2013-02-22T08:19:04.477 回答