我正在尝试将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();
}
}
}