2013-02-28 54 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文件已收到并播放正常。