2017-02-14 110 views
3

我已經編寫了此代碼以便將文件從服務器傳輸到客戶端,但我只能發送小於1 Kb的文件大小。我想發送任何大小的文件。這將是非常有益的,如果你可以修改我的代碼:如何在Android中使用套接字發送大文件

文件發送方(Server代碼)

protected void onCreate(Bundle savedInstanceState) { 

     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     infoIp = (TextView) findViewById(R.id.infoip); 
     infoPort = (TextView) findViewById(R.id.infoport); 

     infoIp.setText(getIpAddress()); 

     serverSocketThread = new ServerSocketThread(); 
     serverSocketThread.start(); 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 

     if (serverSocket != null) { 
      try { 
       serverSocket.close(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 

    private String getIpAddress() { 
     String ip = ""; 
     try { 
      Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface.getNetworkInterfaces(); 
      while (enumNetworkInterfaces.hasMoreElements()) { 
       NetworkInterface networkInterface = enumNetworkInterfaces.nextElement(); 
       Enumeration<InetAddress> enumInetAddress = networkInterface.getInetAddresses(); 

       while (enumInetAddress.hasMoreElements()) { 
        InetAddress inetAddress = enumInetAddress.nextElement(); 

        if (inetAddress.isSiteLocalAddress()) { 
         ip += "SiteLocalAddress: "+ inetAddress.getHostAddress() + "\n"; 
        } 
       } 
      } 

     } catch (SocketException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      ip += "Something Wrong! " + e.toString() + "\n"; 
     } 

     return ip; 
    } 

    public class ServerSocketThread extends Thread { 

     @Override 
     public void run() { 
      Socket socket = null; 

      try { 
       serverSocket = new ServerSocket(SocketServerPORT); 
       MainActivity.this.runOnUiThread(new Runnable() { 

        @Override 
        public void run() { 
         infoPort.setText("I'm waiting here: " 
           + serverSocket.getLocalPort()); 
        }}); 

       while (true) { 
        socket = serverSocket.accept(); 
        FileTxThread fileTxThread = new FileTxThread(socket); 
        fileTxThread.start(); 
       } 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } finally { 
       if (socket != null) { 
        try { 
         socket.close(); 
        } catch (IOException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
       } 
      } 
     } 
    } 

    public class FileTxThread extends Thread { 
     Socket socket; 
     FileTxThread(Socket socket){ 
      this.socket= socket; 
     } 

     @Override 
     public void run() { 
      File file = new File(Environment.getExternalStorageDirectory(),"test.mp3"); 

      byte[] bytes = new byte[(int) file.length()]; 

      BufferedInputStream bis; 
      try { 
       bis = new BufferedInputStream(new FileInputStream(file)); 
       bis.read(bytes, 0, bytes.length); 
       OutputStream os = socket.getOutputStream(); 
       os.write(bytes, 0, bytes.length); 
       os.flush(); 
       // socket.close(); 

       final String sentMsg = "File sent to: " + socket.getInetAddress(); 
       System.out.println("socket getIntentAddress "+socket.getInetAddress()); 
       MainActivity.this.runOnUiThread(new Runnable() { 

        @Override 
        public void run() { 
         Toast.makeText(MainActivity.this,sentMsg,Toast.LENGTH_LONG).show(); 

        }}); 

      } catch (FileNotFoundException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
       System.out.println("Ioexception"+e); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
       } finally { 
       try { 
        socket.close(); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
        System.out.println("Ioexception"+e); 
       } 

文件接收方(客戶端代碼)

buttonConnect.setOnClickListener(new OnClickListener(){ 

      @Override 
      public void onClick(View v) { 
       ClientRxThread clientRxThread = 
         new ClientRxThread(editTextAddress.getText().toString(),SocketServerPORT); 

       clientRxThread.start(); 
      }}); 
    } 

    private class ClientRxThread extends Thread { 
     String dstAddress; 
     int dstPort; 

     ClientRxThread(String address, int port) { 
      dstAddress = address; 
      dstPort = port; 
     } 

     @Override 
     public void run() { 
      Socket socket = null; 

      try { 
       socket = new Socket(dstAddress, dstPort); 


       File file = new File(Environment.getExternalStorageDirectory(),"test.mp3"); 

       byte[] bytes = new byte[1024]; 


       InputStream is = socket.getInputStream(); 
       FileOutputStream fos = new FileOutputStream(file); 
       BufferedOutputStream bos = new BufferedOutputStream(fos); 
       int bytesRead = is.read(bytes, 0, bytes.length); 
       bos.write(bytes, 0, bytesRead); 
       bos.close(); 
       // socket.close(); 

       MainActivity.this.runOnUiThread(new Runnable() { 

        @Override 
        public void run() { 
         Toast.makeText(MainActivity.this,"Finished",Toast.LENGTH_LONG).show(); 
        }}); 

      } catch (IOException e) { 

       e.printStackTrace(); 

       final String eMsg = "Something wrong: " + e.getMessage(); 

       MainActivity.this.runOnUiThread(new Runnable() { 

        @Override 
        public void run() { 
         Toast.makeText(MainActivity.this,eMsg,Toast.LENGTH_LONG).show(); 
         System.out.println("run"+eMsg); 
        }}); 

      } finally { 
       if(socket != null){ 
        try { 

         socket.close(); 
        } catch (IOException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 

        } 

請幫助爵士!提前致謝!

+0

如果您嘗試發送更大的文件,會發生什麼情況?你有什麼錯誤嗎? –

+0

數據僅傳輸1kb大小的文件,但我想傳輸大文件。請幫助我,如果有任何解決方案。謝謝你 –

+0

看到我的答案。您的客戶沒有讀取所有可用數據。 –

回答

1

我可以發誓你的原始問題是關於接收,而不是發送(和其他答案似乎表明相同)。無論如何,要發送大文件,您可以將整個文件讀入一個足夠大的緩衝區(假定該文件的大小合理),或者使用循環以可管理大小的塊讀取它然後處理(發送)塊。

回答您的原始問題,您只讀取1024,因爲這是您正在嘗試閱讀的所有內容。你已經在1024分配了你的緩衝區,只能讀一次。

  byte[] bytes = new byte[1024]; 
... 
      int bytesRead = is.read(bytes, 0, bytes.length); 
      bos.write(bytes, 0, bytesRead); 
      bos.close(); 

嘗試

byte[] bytes = new bytes[1024]; 
... 
int bytesRead = is.read(bytes, 0, bytes.length); 
while(bytesRead > 0) { 
    bos.write(bytes, 0, bytesRead); 
    bytesRead = is.read(bytes, 0, bytes.length); 
} 
... 

,並在同一個異常的情況下,try/catch塊中的適當位置包裹你的代碼。

1

您需要將接收的字節放入一個循環中,該循環只有在接收到所有數據時纔會完成。例如: -

byte[] bytes = new byte[1024]; 
InputStream is = socket.getInputStream(); 
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file)); 
while (true) { 
    int bytesRead = is.read(bytes); 
    if (bytesRead < 0) break; 
    bos.write(bytes, 0, bytesRead); 
    // Now it loops around to read some more. 
} 
bos.close(); 
+0

請確保你在服務或線程中使用它,因爲活動可能在任何時候被終止。前臺服務保持活動狀態。如果你想在後臺服務中處理這個問題,請確保你保存了「狀態」,然後繼續運行。服務返回 –

+0

你是否嘗試過單步執行IDE中的代碼? –

+0

使用此代碼我發送55mb大小的文件正確。但是當我試圖傳輸500MB大小的文件,然後它顯示錯誤 - 拋出OutOfMemoryError「未能分配360318346字節分配5802592空閒字節和87MB,直到OOM」和應用程序自動崩潰System.err:java.net.SocketException:套接字關閉 謝謝。 –