2017-02-14 49 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:套接字关闭 谢谢。 –