0

これは、私がアプローチするいくつかの異なる方法を試している課題です。

TCPをエミュレートするためにUDPを使用しています。今日の初めに、UDPを介してファイル転送を機能させることができましたが、もちろん、「セグメント」の再送信のチェックでエラーが発生しないため、IDと一部のバイトデータを受け取るメッセージタイプクラスを実装しようとはしていません。

デバッグすると、メッセージオブジェクトを正しく作成していて、publicbyte[]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);
    }

DESERIALIZEメソッド

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

UDPRECEIVER

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 に答える