0

現在、TCP 経由で 1 つのテスト mp3 ファイルを提供する C# サーバーをセットアップしました。ファイルを送信するコードは次のとおりです。

    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 ファイル (曲全体) の短いスニペットのみを取得します。こちらも少し跳ねます。長さは同じではなく、演奏される曲のセクションは毎回異なります。

曲の完全な再生を提供するように、順序付けられた方法で完全なファイルを受け取るにはどうすればよいですか?

私はこれを迂回しようとしましたが、クライアントに疑わしいファイルサイズを伝え、すべてのデータが受信されるまでループを実行する必要があると考えていますが、それが正しい場合にこれを正常に実装する方法はわかりません解決。

どこが間違っているか、または修正するために何ができるかについての指針は大歓迎です!!

4

1 に答える 1

1

これについて何の答えも得られなかったので、私はもう少し掘り下げました。2 つの点が間違っていました。まず、ストリームのサイズを int サイズのヘッダーとしてストリームに含めていませんでした。小さいファイルの場合、これは問題にならないことは理解していますが、ファイル サイズが大きくなると、ストリーム全体が受信されたことを確認する必要があります。

これにより、別の問題が発生しました。byte[] フォーム c# として送信していた int は、Java で正しい値を返していませんでした。Java は、バイトではなく sbytes -128 から 127 の範囲を使用することが判明しました。これには、int に変換するためのコードが少し必要でした。次に、予想されるストリームの実際のサイズで byte[] バッファーを読み取り可能に渡すようにリーダーに指示できます = 出来上がり。MP3 ファイルが受信され、正常に再生されます。

于 2013-03-04T22:07:43.650 に答える