1

オーディオ ストリーミング用のクライアント/サーバー システムを実装しようとしています。クライアントはファイルを要求し、サーバーはそれを送信する必要があります。その後、クライアントはすぐにファイルを再生する必要があります。rtp および rtsp プロトコルに基づくいくつかのソリューションを読みましたが、それらは私のユース ケースには複雑すぎます。TCP ソケットを介した単純なファイル転送を使用したいのですが、クライアントはダウンロードの終了を待たずにすぐにオーディオ ファイルを再生する必要があります。この解決策は可能ですか?

これは私が使用しているコードです。

サーバ:

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

public class ConcurTCPServer implements Runnable 
{
    static ServerSocket listenSocket;
    Socket sock = null;
    static final int port = 12345;
    InputStream recvStream = null;
    OutputStream sendStream = null;
    FileInputStream fis = null;
    BufferedInputStream bis = null;
    String request;
    String response;

    public ConcurTCPServer(Socket s) throws IOException, UnknownHostException 
    {
        sock = s;
        recvStream = sock.getInputStream();
        sendStream = sock.getOutputStream();
    }

    public void run()
    {
        getRequest();
        process();
        sendResponse();
        close();
    }

    void getRequest()
    {
        try
        {
            int dataSize;
            byte[] recvBuff = new byte[1024];
            dataSize = recvStream.read(recvBuff, 0, 1024);
            request = new String(recvBuff, 0, dataSize);
            System.out.println("Request for: " + request);
        }
        catch (IOException ex)
        {
            ex.printStackTrace();
        }
    }

    void process()
    {
        //TODO
    }

    void sendResponse()
    {       
        try
        {
            File myFile = new File ("/Users/user/Desktop/" + request);
            byte [] mybytearray  = new byte [(int)myFile.length()];
            fis = new FileInputStream(myFile);
            bis = new BufferedInputStream(fis);
            bis.read(mybytearray,0,mybytearray.length);
            System.out.println("Sending..." + myFile.getPath() + ". Dimension: " + myFile.length());
            sendStream.write(mybytearray,0,mybytearray.length);
            sendStream.flush();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    void close()
    {
        try
        {
            System.out.println("Done");
            recvStream.close();
            sendStream.close();
            sock.close();
        }
        catch (IOException ex)
        {
            ex.printStackTrace();
        }
    }

    public static void main(String [] args) throws IOException
    {
        listenSocket = new ServerSocket(port);
        while(true)
        {
            System.out.println("Waiting...");
            ConcurTCPServer server = new ConcurTCPServer(listenSocket.accept());
            System.out.println("Client connected");
            Thread thread = new Thread(server);
            thread.start();
        }
    }
}

クライアント:

    import java.net.*;
import java.io.*;

import sun.audio.AudioData;
import sun.audio.AudioDataStream;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;

public class TCPClient 
{
    Socket sock;
    OutputStream sendStream;
    InputStream recvStream;
    AudioStream audioStream;
    AudioData audiodata;
    AudioDataStream audioDataStream;
    String request;
    String response;

    public TCPClient(String server, int port) throws IOException, UnknownHostException 
    {
        sock = new Socket(server, port);
        sendStream = sock.getOutputStream();
        recvStream = sock.getInputStream();
    }

    void makeRequest(String word)
    {
        request = word;
    }

    void sendRequest()
    {
        try
        {
            byte[] sendBuff = new byte[request.length()];
            sendBuff = request.getBytes();
            System.out.println("Sending request for: " + request);
            sendStream.write(sendBuff, 0, sendBuff.length);
        }
        catch (IOException ex)
        {
            ex.printStackTrace();
        }
    }

    void getResponse()
    {
        try
        {
            System.out.println("Playing...");
            audioStream = new AudioStream(recvStream);
            audiodata = audioStream.getData();
            audioDataStream = new AudioDataStream(audiodata);
            AudioPlayer.player.start(audioDataStream);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    void close()
    {
        try
        {
            System.out.println("Done");
            if (audioStream != null) audioStream.close();
            sendStream.close();
            recvStream.close();
            sock.close();
        }
        catch (IOException ex)
        {
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException
    {
        final int servPort = 12345;
        final String servName = "localhost";
        TCPClient client = new TCPClient(servName, servPort);
        System.out.println("Connected");
        client.makeRequest("welcome.wav");
        client.sendRequest();
        client.getResponse();
        client.close();
    }
}

小さな .wav でしか動作しないので、実際にファイルをストリーミング再生するわけではないと思いますが、ダウンロード後すぐに再生が始まります。ファイル サイズが約 1Mb 以上の場合、クライアントは例外を返します。

java.io.IOException: could not create AudioData object
at sun.audio.AudioStream.getData(AudioStream.java:125)
at com.dicet.unisalento.TCPClient.getResponse(TCPClient.java:54)
at com.dicet.unisalento.TCPClient.main(TCPClient.java:88)

一方、サーバーは例外を返します。

java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)
at java.net.SocketOutputStream.write(SocketOutputStream.java:159)
at com.dicet.unisalento.ConcurTCPServer.sendResponse(ConcurTCPServer.java:70)
at com.dicet.unisalento.ConcurTCPServer.run(ConcurTCPServer.java:35)
at java.lang.Thread.run(Thread.java:744)

助けてください。

周りを見回すと、HTTP プログレッシブ ダウンロードを使用する必要があることがわかりましたが、HTTP プログレッシブ ダウンロードを使用したクライアント/サーバーの実装例が見つかりません。

4

0 に答える 0