2013-04-17 3 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_SIZE1024*512 값으로 설정된다.

나는 TCP_BUFFER_SIZE의 값을 많이 변경하려고했지만 행운이 없었다. 나는 Apache Commons IOUtils로 스트림 복사의 구현을 대체했습니다.

업데이트를 나를 도와 : 내가 파일을 사용하지 않고 일반 소켓을 사용하여 간단한 데이터 전송을 시도 할 다음과 같은 전송 그래프 Graph of transfer speed

+0

정말 자주 버퍼링을해야합니까, 버퍼링의 전체 요점은 시스템 콜/플러시의 수를 줄이는 것입니까? –

+0

코멘트 주셔서 감사합니다. 나는 그 플러시를 제거했습니다. 그러나 그것은 단지 2-3 통화 였기 때문에 나에게 도움이되지 못했습니다. – Dipendra

답변

2

은 그것을이 후, Socket.setReceiveBufferSize (int)를 호출하여, 후속 값을 변경하는 것이 가능하다 setReceiveBufferSize() javadoc

에서, 버퍼 오버 것 같다. 그러나 응용 프로그램이 에 RFC1323 에 정의 된대로 64K 바이트보다 큰 수신 창이 허용되게하려면 이 로컬 주소에 바인딩되기 전에 제안 된 값을 ServerSocket에 설정해야합니다. 이것은 ServerSocket이 인수가없는 생성자로 생성 된 이어야하며 setReceiveBufferSize()가 이어야하고 마지막으로 ServerSocket이 (bind()를 호출하여 주소에 바인딩되어야 함)을 의미합니다.

+0

핀 포인트를 주셔서 대단히 감사합니다. 제안대로 코드를 수정했습니다. 이제 속도는 TCP_BUFFER_SIZE = 1024 * 1024 인 2-3Mbps입니다. 하지만 속도는 여전히 훨씬 빨라질 수 있다고 저는 믿습니다. 귀하의 더 많은 도움을 높이 평가 될 것입니다. – Dipendra

0

를 참조하십시오.

연결할 때 100MB의 빈 데이터를 보내는 간단한 서버가 있습니다. 클라이언트가 처리량을보고 할 수있는만큼 빨리 데이터를 읽도록하십시오. 동일한 머신에서 100MB/s 이상을 쉽게 볼 수 있습니다. 일단 이것이 좋은 숫자를 제공하면 안드로이드 클라이언트에서 시도하십시오.