2013-02-18 23 views
0

這是一個任務我正在嘗試幾種不同的方法來處理:數據報傳輸後未能投射物體

我們使用UDP來模擬TCP。今天早些時候,我設法讓文件傳輸在UDP上工作,但是當然iy沒有檢查重新發送'段'的錯誤,所以我沒有試圖實現一個帶有ID和一些字節數據的消息類型類。

調試顯示我我正確地使我的消息對象,然後我使用公共字節[] serialize(Object obj)將我的對象轉換爲UDP數據報傳輸的字節數組。

在接收端,當我將反序列化的對象轉換回消息時,它會崩潰。

CAST失敗

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 CLASS

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

好的,我終於調試了劇組失敗的原因。我沒有考慮到序列化對象的完整字節大小。我將接收緩衝區更改爲「607」,並且演員陣容正常工作。 – 2013-02-18 22:27:49

回答

0

好吧,我終於調試,爲什麼劇組失敗。

我沒有考慮到我的序列化對象的完整字節大小。我將接收緩衝區更改爲607字節,並且轉換正常。