2013-04-17 113 views
1

我正在开发基于wifi的直接文件传输应用程序。我可以看到使用TCP套接字的传输速度并不令人满意。速度通常为1Mbps。每当我分析数据传输图时,我都会看到很多尖峰,很多秒都没有数据传输。我知道传输速度应该更高(可能是20-30Mbps) 请帮助我提高传输速度。 接受该连接将ServerSocket是在java/android中增加TCP套接字的传输速度

private void serverTask() { 
     Log.v(TAG, "server task"); 
     try { 
      serverRunning = true; 
      ServerSocket serverSocket = new ServerSocket(
        DeviceDetailFragment.PORT); 
      serverSocket.setReceiveBufferSize(TCP_BUFFER_SIZE); 


      Socket client = serverSocket.accept(); 

      BufferedInputStream inputstream = new BufferedInputStream(
        client.getInputStream()); 
      // new BufferedInputStream(client.getInputStream(), 8 * 1024); 
      BufferedReader bufferedStream = new BufferedReader(
        new InputStreamReader(inputstream)); 


       fileName = bufferedStream.readLine(); 
       fileSizeInBytes = bufferedStream.readLine(); 
       fileMime = bufferedStream.readLine(); 

       f = new File(Globals.fileSavingLocation + fileName); 

       File dirs = new File(f.getParent()); 
       if (!dirs.exists()) 
        dirs.mkdirs(); 

       if (f.exists()) { 
        f.delete(); 
       } 

       f.createNewFile(); 

     IOUtils.copy(inputstream, new FileOutputStream(f)); 


       serverSocket.close(); 
      } 
      isSuccessful = true; 

     } catch (IOException e) { 
      isSuccessful = false; 
      Log.e(TAG, e.getMessage()); 

     } 
     serverRunning = false; 

    } 

并发送该数据的客户机具有以下代码:

private void clientTask(Intent intent) { 
      String fileUri = intent.getExtras().getString(EXTRAS_FILE_PATH); 
      String host = intent.getExtras().getString(EXTRAS_ADDRESS); 
      String fileName = intent.getExtras().getString(FILE_NAME); 
      String fileMimeType = intent.getExtras().getString(FILE_MIME_TYPE); 
      final long sizeInBytes = intent.getExtras().getLong(FILE_SIZE); 
      Socket socket = new Socket(); 
      int port = intent.getExtras().getInt(EXTRAS_PORT); 

      try { 
       socket.setSendBufferSize(TCP_BUFFER_SIZE); 
       socket.bind(null); 
       socket.connect((new InetSocketAddress(host, port)), 
         SOCKET_TIMEOUT); 

       BufferedOutputStream stream = new BufferedOutputStream(
         socket.getOutputStream()); 
       ContentResolver cr = FileTransferService.this 
         .getApplicationContext().getContentResolver(); 
       InputStream is = null; 

       BufferedWriter bufferStream = new BufferedWriter(
         new OutputStreamWriter(stream)); 


       bufferStream.write(fileName); 
       bufferStream.newLine(); 
       bufferStream.flush(); 
       bufferStream.write(String.valueOf(sizeInBytes)); 
       bufferStream.newLine(); 
       bufferStream.flush(); 

       bufferStream.write(fileMimeType); 
       bufferStream.newLine(); 
       bufferStream.flush(); 


       try { 

        is = new BufferedInputStream(cr.openInputStream(Uri 
          .parse(fileUri))); 

       } catch (FileNotFoundException e) { 

        isSuccessful = false; 

       } 
IOUtils.copy(is, stream); 


       isSuccessful = true; 

      } catch (IOException e) { 
       Log.e(TAG, e.getMessage()); 
       isSuccessful = false; 
      } finally { 
       if (socket != null) { 
        if (socket.isConnected()) { 
         try { 
          socket.close(); 
         } catch (IOException e) { 
          // Give up 
          e.printStackTrace(); 
         } 
        } 
       } 
      } 

TCP_BUFFER_SIZE的值被设置为1024*512

我试了很多改变TCP_BUFFER_SIZE的值,但没有运气。我用Apache Commons IOUtils替换了我的复制流的实现。 帮我出

更新: 请参看下面的图转移 Graph of transfer speed

+0

你是否真的需要频繁刷新你的缓冲区,缓冲的要点是减少系统调用/刷新的次数? –

+0

谢谢你的评论。我已经删除了这些冲洗。然而,它并没有帮助我,因为它只需2-3电话 – Dipendra

回答

2

看来你是超载缓冲区,从setReceiveBufferSize() javadoc

有可能随后更改了值,通过调用 socket的(INT)。然而,如果应用程序希望 以允许接收窗口大于64K字节的,由RFC1323 限定话建议值必须在将ServerSocket被设定之前,它是 绑定到本地地址。这意味着,这将ServerSocket必须与无参数的构造函数创建 ,然后setReceiveBufferSize() 必须被调用,最后将ServerSocket由 绑定到一个地址调用bind()。

+0

谢谢你这么多pinpointing.I纠正我的代码按你的建议。现在速度为2-3 Mbps,TCP_BUFFER_SIZE = 1024 * 1024。但我相信,速度仍然可以更快。您的进一步帮助将高度赞赏。 – Dipendra

0

我会用一个简单的插座不使用文件尝试一个简单的数据传输。

有一个简单的服务器,当您连接时发送100 MB空数据。让客户端以尽可能快的速度读取数据,并报告吞吐量。在同一台机器上,您应该可以轻松看到超过100 MB/s的速度。一旦这给了一个很好的数字在Android客户端上尝试。