Socket和InputStream =>连接由对等异常重置

时间:2016-02-25 15:09:42

标签: java android sockets inputstream

我正在尝试将InputStream的数据流式传输到充当代理的套接字。原因是,我想通过android InputStreams播放MediaPlayer

问题是我总是得到 endto失败:ECONNRESET(由对等方重置连接)异常:

    com.prom.gallery.classes.VideoProxy: [VideoProxy-172]   sendto failed: ECONNRESET (Connection reset by peer)
     java.net.SocketException: sendto failed: ECONNRESET (Connection reset by peer)
         at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:546)
         at libcore.io.IoBridge.sendto(IoBridge.java:515)
         at java.net.PlainSocketImpl.write(PlainSocketImpl.java:504)
         at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:37)
         at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:266)
         at com.prom.gallery.classes.VideoProxy.processRequest(VideoProxy.java:168)
         at com.prom.gallery.classes.VideoProxy.run(VideoProxy.java:110)
         at java.lang.Thread.run(Thread.java:818)
      Caused by: android.system.ErrnoException: sendto failed: ECONNRESET (Connection reset by peer)
         at libcore.io.Posix.sendtoBytes(Native Method)
         at libcore.io.Posix.sendto(Posix.java:176)
         at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:278)
         at libcore.io.IoBridge.sendto(IoBridge.java:513)
         at java.net.PlainSocketImpl.write(PlainSocketImpl.java:504) 
         at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:37) 
         at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:266) 
         at com.prom.gallery.classes.VideoProxy.processRequest(VideoProxy.java:168) 
         at com.prom.gallery.classes.VideoProxy.run(VideoProxy.java:110) 
         at java.lang.Thread.run(Thread.java:818) 

问题

我该如何解决?我的解决方案是附加的,基于https://code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/StreamProxy.java ...我发现我可能需要一个标题来保持套接字打开,但我真的不知道这是不是真的以及如何将它添加到我的解决方案中..

我的自定义类IDownloadableMedia只是直接返回一个简单的流...

我有多个视频源,其中一些仅允许流。为了测试我也使用了一个与url一起使用的源代码,我在下载函数中创建了一个InputStream,如下所示:new URL(url).openStream()。网址有效且有效!

代码

这是我的VideoProxy课程:

public class VideoProxy implements Runnable
{
    public static String createProxyString(VideoProxy proxy, int folderIndex, int mediaIndex,  String uniqueId)
    {
        return String.format("http://127.0.0.1:%d/%s", proxy.getPort(), folderIndex + "-" + mediaIndex + "-" + uniqueId);
    }

    private int port = 0;

    public int getPort()
    {
        return port;
    }

    private boolean mIsRunning = true;
    private ServerSocket mSocket;
    private Thread mThread;

    public void init()
    {
        try
        {
            mSocket = new ServerSocket(port, 0, InetAddress.getByAddress(new byte[] {127, 0, 0, 1}));
            mSocket.setSoTimeout(5000);
            port = mSocket.getLocalPort();
            L.d(this, "Port " + port);
        }
        catch (UnknownHostException e)
        {
            L.e(this, e);
        }
        catch (IOException e)
        {
            L.e(this, e);
        }
    }

    public void start()
    {
        if (mSocket == null)
            throw new IllegalStateException("Proxy has not been initialized!");
        mThread = new Thread(this);
        mThread.start();
    }

    public void stop()
    {
        mIsRunning = false;
        if (mThread != null)
        {
            mThread.interrupt();
            try
            {
                mThread.join(5000);
            }
            catch (InterruptedException e)
            {
                L.e(this, e);
            }
        }
    }

    @Override
    public void run()
    {
        L.d(this, "Run...");
        while (mIsRunning)
        {
            try
            {
                Socket client = mSocket.accept();
                if (client == null)
                    continue;

                L.d(this, "client connected");

                // get data
                String data = readData(client);
                L.d(this, "data: " + data);
                String splitted[] = data.split("-");
                int folderIndex = Integer.parseInt(splitted[0]);
                int mediaIndex = Integer.parseInt(splitted[1]);
                String uniqueId = splitted[2];

                L.d(this, "data splitted: " + folderIndex + ", " + mediaIndex + ", " + uniqueId);

                // get media file
                IDownloadableMedia media = (IDownloadableMedia)RXManager.get().createLoadedSingleFolderObservable(null, null, folderIndex).toBlocking().first().getMedia().get(mediaIndex);

                L.d(this, "media: " + media.getMediaFolder().getName() + " | " + media.getName());

                // download media file
                processRequest(client, media);
            }
            catch (SocketTimeoutException e)
            {
                // Do nothing
            }
            catch (IOException e)
            {
                L.e(this, e);
            }
        }
        L.d(this, "Proxy interrupted - shutting down...");
    }

    private String readData(Socket client)
    {
        InputStream is;
        String firstLine;
        try
        {
            is = client.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            firstLine = reader.readLine();
        }
        catch (IOException e)
        {
            L.e(this, e);
            return null;
        }

        if (firstLine == null)
        {
            L.d(this, "Proxy client closed connection without a request.");
            return null;
        }

        StringTokenizer st = new StringTokenizer(firstLine);
        String method = st.nextToken();
        String uri = st.nextToken();
        L.d(this, uri);
        String realUri = uri.substring(1);
        L.d(this, realUri);
        return realUri;
    }

    private void processRequest(Socket client, IDownloadableMedia downloadableMedia) throws IllegalStateException, IOException
    {
        if (downloadableMedia == null)
            return;
        L.d(this, "downloading...");

        InputStream data = downloadableMedia.download();
        try
        {
            int readBytes = -1;
            // Stream content...
            byte[] buff = new byte[1024 * 50];
            while (mIsRunning && (readBytes = data.read(buff, 0, buff.length)) != -1)
                client.getOutputStream().write(buff, 0, readBytes);
        }
        catch (Exception e)
        {
            L.e(this, e);
        }
        finally
        {
            if (data != null)
                data.close();
            client.close();
        }
    }
}

0 个答案:

没有答案