2013-02-28 56 views
0

我已經建立了一個C#服務器,它目前通過TCP提供一個測試mp3文件。發送文件的代碼如下從C#服務器流式MP3到Android

public void RunStreamer() 
    { 
     log.MakeLog("Starting streamer"); 
     Run = true; 
     //Need to look into how to thread this to not block the main window 
     TcpListener listen = new TcpListener(localAddr, _port); 
     listen.Start(); //startlistening to client requests 

      //blocks until a client request comes in 
     for (; ;) 
     { 
      Socket socket = listen.AcceptSocket(); 
      if (socket.Connected) 
      { 

       SendFileToClient(socket); 
       socket.Disconnect(false); 
      } 
     } 

    } 

    void SendFileToClient(Socket socket) 
    { 
     log.MakeLog("Connection made"); 
     NetworkStream netStream = new NetworkStream(socket); 
     StreamWriter writer = new StreamWriter(netStream); 
     //Todo - set specfified file - this file just for test 
     FileStream filestream = File.Open(@"C:\MusicTest\Test.mp3", FileMode.Open, FileAccess.Read, FileShare.Read); 
     filestream.CopyTo(netStream); 
     netStream.Flush(); 
     netStream.Close(); 


    } 

在我的測試Android的設置我點擊一個按鈕向服務器的呼叫:

public void btngo_click(View v) 
{ 
    final TcpClient client = new TcpClient(); 

    new Thread(new Runnable(){ 
     @Override 
     public void run() { 
      final MediaPlayer mediaPlayer = new MediaPlayer(); 
      client.GetStream(); 
      runOnUiThread(new Runnable(){ 
       public void run() 
       { 
        int length = client.GetLength(); 
        if(length > 0) 
        { 
         byte[] result = client.GetResult(); 
         try { 
          // create temp file that will hold byte array 
          File tempMp3 = File.createTempFile("test", "mp3", getCacheDir()); 
          tempMp3.deleteOnExit(); 
          FileOutputStream fos = new FileOutputStream(tempMp3); 
          fos.write(result); 
          fos.close(); 


          mediaPlayer.reset(); 

          FileInputStream fis = new FileInputStream(tempMp3); 
          mediaPlayer.setDataSource(fis.getFD()); 

          mediaPlayer.prepare(); 
          mediaPlayer.start(); 
         } catch (IOException ex) { 
          String s = ex.toString(); 
          ex.printStackTrace(); 
         } 

        } 
       } 
      }); 

     } 
    }).start(); 

} 

流在TcpClient類接收這是如下:

public class TcpClient { 

public final static String SERVER_ADDRESS = "127.0.0.1"; 
public final static int SERVER_PORT = 65000; 
public String TotalResult; 
public int Length; 
byte[] result = new byte[21000000]; 


public TcpClient() 
{ 



} 

public int GetLength() 
{ 
    return Length; 

} 

public byte[] GetResult() 
{ 

    return result; 

} 

public void GetStream() 
{ 
    try 
    { 

     final Socket socket = new Socket("192.0.0.5", 85000); 
     final InputStream input = new BufferedInputStream(socket.getInputStream()); 
     ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 

     int nread; 


     while((nread = input.read(result, 0, result.length)) != -1) 
     { 

      buffer.write(result, 0, nread); 
     } 
     buffer.flush(); 

     //input.read(result); 
     Length = result.length; 


     input.close(); 
     socket.close(); 

    } catch (UnknownHostException e) { 
     String exc = e.getMessage(); 
     e.printStackTrace(); 
    } catch (IOException e) { 
     String exc2 = e.getMessage(); 
     e.printStackTrace(); 
    } 

} 

}

隨着道歉這裏所有的代碼是我的問題。

我正在接收流。臨時MP3文件已創建並且媒體播放器啓動。然後,我只能得到測試MP3文件的短片段(這是一首完整的歌曲)。它也跳了一下。長度不一樣,每次播放的歌曲部分都不相同。

如何以有序方式接收完整文件,以便能夠提供歌曲的完整播放。

我試圖繞過這一點,並有一個想法,我需要告訴我的客戶它應該懷疑什麼文件大小,然後執行一些循環,直到收到所有數據,雖然我不知道如何成功實現這個if這是正確的解決方案。

任何指向哪裏我錯了什麼或我可以做什麼來糾正將不勝感激!

+0

我認爲這是通過Wi-Fi? – MyCodeSucks 2013-02-28 22:26:49

+0

是的,這是通過無線上網 - 我已經在模擬器上在桌面和手機上測試過,結果相同 – Luthervd 2013-02-28 22:36:55

回答

0

收到沒有答案後,我挖了一點。有兩件事是錯誤的: 首先,我沒有將流的大小作爲int大小的頭部包含在我的流中。據我所知,對於較小的文件,這不會是一個問題,但隨着文件大小的增加,有必要確保已收到整個流。

這又引發了另一個問題。我以byte []形式發送的int在C#中沒有返回正確的值。原來Java使用sbytes -128到127範圍而不是字節。這然後涉及到一些代碼轉換爲一個int。那麼我可以指導讀者將byte []緩衝區傳遞給預期流的實際大小=瞧它的工作。 MP3文件已收到並播放正常。