2016-02-24 59 views
1

我創建了一個android到pc客戶端 - 服務器應用程序,並且貫穿我的應用程序的其他功能,我使用ObjectOutputStream.writeObject(AbstractPacket對象)來發送控件和數據b/w我的應用程序和他們都工作正常,現在當我試圖發送一個文件(例如:一個小的JPG/PNG文件),在將文件字節發送到服務器端並重新創建原始jpg文件後,該文件顯示它已損壞,而不是顯示,但其大小是完全相同的客戶端Android應用程序發送。 這裏的一些代碼,數據傳輸不工作使用ObjectOutputStream.writeObject()

客戶端:(文件字節陣列)

byte [] mybytearray = new byte [(int)myFile.length()]; 

FileInputStream fis = new FileInputStream(myFile); 

BufferedInputStream bis = new BufferedInputStream(fis); 

bis.read(mybytearray, 0, mybytearray.length); 

String filename= myFile.getName(); 

FileTransferPacket packet = new FileTransferPacket(mybytearray,mybytearray.length,filename); 
TCPconnection.sendPacket(packet); 

FileTransferPacket擴展AbstractPacket:

public class FileTransferPacket extends AbstractPacket implements Serializable { 


byte[] bytes; 
long size; 
String filename; 

public FileTransferPacket(byte[] bytes,long size,String filename) { 
super(Protocol.Command.FILE_TRANSFER); 
this.bytes = bytes; 
this.size = size; 

this.filename = filename; 
} 

public byte[] getBytes() { 
return bytes; 
} 

public long getSize() {return size; } 

public String getFilename() {return filename; } 
} 

以下是我送的包對象到服務器:

public void sendPacket(AbstractPacket packet) throws IOException { 
    connectionOutput.writeObject(packet); 
    connectionOutput.flush(); 
    connectionOutput.reset(); 

    } 

在服務器端,我讀取如下對象:

AbstractPacket packet =(AbstractPacket)connectionInput.readObject();

receiver.handleReceiveData(packet,connection);

public synchronized void handleReceiveData(AbstractPacket packet, TcpConnection connection) { 

String filename=packet.getFilename(); 
long size= packet.getSize(); 

byte [] mybytearray = new byte [(int)size]; 

byte[] myByteArray=packet.getBytes(); 

String userHomeFolder = System.getProperty("user.home"); 

userHomeFolder+="\\Desktop\\"+filename; 

try { 
FileOutputStream fos = new FileOutputStream(userHomeFolder); 

BufferedOutputStream bos = new BufferedOutputStream(fos); 

bos.write(mybytearray, 0 , (int)size); 

bos.flush(); 
fos.close(); 
bos.close(); 

} catch (IOException e) { 
e.printStackTrace(); 
} 
} 

有人可以告訴我這裏真的有什麼問題,請建議如何解決它們。

經過一番搜索,我沒有發現,也許我可以解決,如果我用正常OutputStreams只發送文件的字節組服務器,它可以工作:

outputStream.write(mybytearray,0,mybytearray.length) ;

但是在我的整個應用程序中,我使用了ObjectoutputStream,所以如何在一個套接字上同時包含這兩種類型的流,在服務器端又如何將傳入數據區分爲Object/bytesbuffer。

回答

1

您可以添加控制字節來指示流的類型。 下面是示例代碼的工作原理。

這有點棘手。 如果可能的話,使用不同的端口號會更簡單。

import java.io.*; 

public class Main { 

    public static void main(String[] args) throws IOException, ClassNotFoundException { 
     // File stream. 
     FileOutputStream fos = new FileOutputStream("test1.txt"); 
     BufferedOutputStream bos = new BufferedOutputStream(fos); 

     // add controll bytes. 
     bos.write(0); 
     bos.write("file contents".getBytes()); 
     bos.close(); 

     // Object stream. 
     FileOutputStream fos2 = new FileOutputStream("test2.txt"); 
     // add controll bytes. 
     fos2.write(1); 
     ObjectOutputStream oos = new ObjectOutputStream(fos2); 
     Exception serializableObj = new RuntimeException("serialize test"); 

     oos.writeObject(serializableObj); 
     oos.close(); 

     readStream(new FileInputStream("test1.txt")); 
     readStream(new FileInputStream("test2.txt")); 
    } 

    private static void readStream(InputStream in) throws IOException, ClassNotFoundException { 
     int controll = in.read(); 
     if (controll == 0) { // File stream 
      BufferedInputStream bis = new BufferedInputStream(in); 
      FileOutputStream fos = new FileOutputStream("test3.txt"); 
      BufferedOutputStream bos = new BufferedOutputStream(fos); 
      byte[] buff = new byte[1024]; 
      while (true) { 
       int ret = bis.read(buff); 
       if (ret < 0) { 
        break; 
       } 
       bos.write(buff, 0, ret); 
      } 
      in.close(); 
      bos.close(); 

      BufferedReader br = new BufferedReader(new FileReader("test3.txt")); 
      String line = br.readLine(); 
      System.out.println("line: " + line); 
      assert (line.equals("file contents")); 
      br.close(); 
     } else if (controll == 1) { // Object stream 
      ObjectInputStream ois = new ObjectInputStream(in); 
      RuntimeException e = (RuntimeException)ois.readObject(); 
      assert (e instanceof RuntimeException); 
      assert (e.getMessage().equals("serialize test")); 
      System.out.println("message: " + e.getMessage()); 
      ois.close(); 
     } 

    } 
}