Socket을 이용해서 실시간 라디오 재생을 구현할때의 문제입니다.
현재 안드로이드에서 실시간 라디오 재생을 구현하고 있습니다.
한정된 파일 크기가 아니라 24시간 재생을 하는것이지요.
그런데 라디오 재생을 시작하고 15~20분정도 지나면 꼭 라디오 재생이 멈춰버립니다.
Broken pipe 라는 에러가 발생되면서요.
관련 정보들을 많이 찾아봤지만 서버측과 이런저런 이유로 연결이
끊기는 경우에 발생한다 외에 이에 대한 처리방법은 아직 찾지 못했습니다.
관련 로직을 간단히 말씀드리자면
Socket을 열고 웹에서 관련 data를 InputStream으로 가져와서
Socket의 OutputStream에 써내려 가는 것입니다.
에러가 나는곳은 아래 코드에서 client.getOutputStream().write(buff, 0, readBytes); 이 부분이고요.
byte[] buff = new byte[1024 * 50]; while (isRunning && (readBytes = data.read(buff, 0, buff.length)) != -1) { client.getOutputStream().write(buff, 0, readBytes); }
라디오를 재생하면 할수록 cpu가 올라간걸 보니 cpu가 너무 높아지면 종료가 되는건지...
(byte를 쓰면 쓸수록 cpu에 부담이 된다면 이건 어떻게 처리를 해야 될까요?)
byte크기를 1024 * 50에서 50으로 줄여보니 1분도 안되서 종료가 된걸 보면 byte크기 문제인가
싶어서 더 늘려도 줘봤지만 맞는 방법이 아닌거같고 또 이렇게 해도 1024 * 50으로 했을때와
별차이 없는 시간에 종료가 되더라고요. (cpu문제인가?)
이방법 저방법 써보다가 여러가지 문제로(몇초마다 끊겨 들리거나 안드로이드 특정 버전에서는 몇분후 먹통이 되는등의)
Socket을 이용해서 했는데 재생은 깔끔하게 잘 되는데 몇분후에 끊겨버리니 머리가 아프네요..@.@;;
혹시 문제원인이나 해결방법을 아시는분 계시면 도움 부탁드립니다.
아래는 관련 메서드 코드 입니다.
private void processRequest(HttpRequest request, Socket client) throws IllegalStateException, IOException { if (request == null) { return; } Log.d(LOG_TAG, "processing"); String url = request.getRequestLine().getUri(); HttpResponse realResponse = download(url); if (realResponse == null) { return; } Log.d(LOG_TAG, "downloading..."); InputStream data = realResponse.getEntity().getContent(); StatusLine line = realResponse.getStatusLine(); HttpResponse response = new BasicHttpResponse(line); response.setHeaders(realResponse.getAllHeaders()); Log.d(LOG_TAG, "reading headers"); StringBuilder httpString = new StringBuilder(); httpString.append(response.getStatusLine().toString()); httpString.append("\n"); for (Header h : response.getAllHeaders()) { httpString.append(h.getName()).append(": ").append(h.getValue()).append( "\n"); } httpString.append("\n"); Log.d(LOG_TAG, "headers done"); try { byte[] buffer = httpString.toString().getBytes(); int readBytes = -1; Log.d(LOG_TAG, "writing to client"); client.getOutputStream().write(buffer, 0, buffer.length); // Start streaming content. byte[] buff = new byte[1024 * 50]; while (isRunning && (readBytes = data.read(buff, 0, buff.length)) != -1) { client.getOutputStream().write(buff, 0, readBytes); } } catch (Exception e) { Log.e("StreamProxy Check1", e.getMessage(), e); } finally { if (data != null) { data.close(); } client.close(); } } private HttpResponse download(String url) { DefaultHttpClient seed = new DefaultHttpClient(); SchemeRegistry registry = new SchemeRegistry(); registry.register( new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); SingleClientConnManager mgr = new MyClientConnManager(seed.getParams(), registry); DefaultHttpClient http = new DefaultHttpClient(mgr, seed.getParams()); HttpGet method = new HttpGet(url); HttpResponse response = null; try { Log.d(LOG_TAG, "starting download"); response = http.execute(method); Log.d(LOG_TAG, "downloaded"); } catch (ClientProtocolException e) { Log.e(LOG_TAG, "Error downloading", e); } catch (IOException e) { Log.e(LOG_TAG, "Error downloading", e); } return response; }
;;; 답변이라기보다는....
while문 안에서 클라이언트로 send를 계속하게 되면
클라이언트가 처리하지 못할 수도 있으니까요.
출력 버퍼가 전송이 완료 된후에 전송하거나
일정시간 대기후에 전송하시는게 좋지 않을까 생각됩니다.
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
감사합니다.
답변 감사드립니다.
제가 이해를 잘 못해서 그러는건지 모르겠는데... 실시간으로 재생되는 라디오라서 무한정으로
받아야 하는데 출력 버퍼가 전송이 완료 된후에 전송이 가능한지...(완료가 안되지 않나요?)
일정시간 대기후에 전송한다고 해도 언젠가는 동일한 문제가 발생하지 않나 싶은데...
제가 네트웍처리쪽은 거의 해본적이 없어서 어려움이 많네요. 일단 말씀하신데로
일정시간 뒤에 전송하는 방법으로 해봐야겠습니다. 답변 감사드려요~~
댓글 달기