2013-04-17 4 views
1

Я разрабатываю приложение для передачи файлов на основе прямых Wi-Fi. Я вижу, что скорость передачи с использованием TCP-сокета не является удовлетворительной. Скорость обычно составляет 1 Мбит/с. Всякий раз, когда я анализирую график передачи данных, я вижу много всплесков и много секунд без передачи данных вообще. Я знаю, что скорость передачи должна быть намного выше (может быть 20-30 Мбит/с) Пожалуйста, помогите мне в увеличении скорости передачи. ServerSocket, который принимает соединение являетсяУвеличьте скорость передачи TCP-сокета в java/android

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. Помогите мне

Update: Пожалуйста, обратитесь к следующей передаче графу Graph of transfer speed

+0

Нужно ли вам часто буферизовать буфер так, чтобы вся буферизация уменьшала количество системных вызовов/флешей? –

+0

Благодарим вас за комментарий. Я удалил эти флеши. Тем не менее, это не помогло мне, так как это было всего лишь 2-3 звонка. – Dipendra

ответ

2

кажется, что вы перегрузки буфера, из setReceiveBufferSize() javadoc

Это можно изменить значение в дальнейшем, с помощью вызова Socket.setReceiveBufferSize (INT). Однако, если приложение желает , чтобы разрешить окно приема размером более 64 Кбайт, как определено RFC1323 , тогда предлагаемое значение должно быть установлено в ServerSocket до того, как оно будет , связанное с локальным адресом. Это означает, что ServerSocket должен быть , созданный с помощью конструктора без аргументов, тогда необходимо вызвать setReceiveBufferSize() и, наконец, ServerSocket привязан к адресу , вызывающего bind().

+0

Большое вам спасибо за то, что вы указали. Я исправил свой код в соответствии с вашим предложением. Теперь скорость составляет 2-3 Мбит/с с TCP_BUFFER_SIZE = 1024 * 1024. Но я считаю, что скорость может быть намного быстрее. Ваша дальнейшая помощь будет высоко оценена. – Dipendra

0

Я хотел бы попробовать простую передачу данных с использованием обычного гнезда без использования файлов.

Имейте простой сервер, который отправляет 100 МБ пустых данных при подключении. Попросите клиента прочитать эти данные так быстро, как может сообщить отчет о пропускной способности, которую он получил. На той же машине вы должны видеть более 100 МБ/с. Как только это даст хороший номер, попробуйте его на Android-клиенте.