소켓을 통해 서버에서 전송받은 .mp4 녹음 파일을 안드로이드 어플리케이션에서 재생하려고 했는데

 

다음과 같은 예외를 만났다.

 

error (1, -2147483648)
java.io.IOException: Prepare failed.: status=0x1
at android.media.MediaPlayer.prepare(Native Method)

 

	if ( player == null )
	{
		player = new MediaPlayer();
		player.setOnCompletionListener(comlistener);
	}
	player.setDataSource(filePath);
	player.prepare();
	player.start();

 

그래서 위와 같이 되어 있던 소스를 다음과 같이 FileDescriptor를 이용하도록 바꾸어보았다.

(참고로, 'player' 변수의 null 검사 부분의 조건문은 이 글에서 별로 중요하지 않다. 단지 변수의 객체 타입을 파악하기 쉽도록 하기 위해 제외하지 않았다.)

 

	if ( player == null )
	{
		player = new MediaPlayer();
		player.setOnCompletionListener(comlistener);
	}
				
	File sourceFile = new File(filePath);
	if ( sourceFile.exists() )
	{
		FileInputStream fs = new FileInputStream(sourceFile);
		FileDescriptor fd = fs.getFD();
		fs.close();
		player.setDataSource(fd);
		player.prepare();
		player.start();
	}

 

그러자 이번엔 다음과 같은 예외가 발생했다.

 

Unable to to create media player
java.io.IOException: setDataSourceFD failed.: status=0x80000000
at android.media.MediaPlayer.setDataSource(Native Method)

 

스트림이 닫히는 순서가 문제일까 싶어서 다음과 같이 FileInputStream의 닫는 순서를 약간 변경해보았다.

 

	if ( player == null )
	{
		player = new MediaPlayer();
		player.setOnCompletionListener(comlistener);
	}
				
	File sourceFile = new File(filePath);
	if ( sourceFile.exists() )
	{
		FileInputStream fs = new FileInputStream(sourceFile);
		FileDescriptor fd = fs.getFD();
		player.setDataSource(fd);
		fs.close();	// 데이터 소스를 설정한 후 스트림을 닫았다.
		player.prepare();
		player.start();
	}

 

이번엔 파일이 정상적으로 다운로드 되어있는 경우, 문제 없이 재생이 되었다.

 

0x80000000 예외일 경우 대부분 파일이 잘못된 경우가 많으니 파일 크기를 확인하거나, 먼저 다른 플레이어로 재생해보는 편이 좋다.

Posted by Kugi
,



자바로 C언어로 구현된 서버와 소켓 통신을 하려던 중 다음과 같은 예외가 발생하였다.

 

java.io.StreamCorruptedException: invalid stream header: 6572726F
   at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
   at java.io.ObjectInputStream.<init>(Unknown Source)

 

 

원인은 예외메시지가 보여주는 것처럼 스트림헤더가 유효하지 않기 때문이었다.

 

C언어 기반의 서버와 통신하기 위해서는 ObjectStream이 아닌 DataStream을 사용해야 하는데

 

습관적으로 ObjectOutputStream과 ObjectInputStream를 사용해서 발생한 문제였다.

 

이것은 왜냐하면 JAVA 기반과 C언어 기반이 소켓통신을 하기 위해서는 read와 write를 할 때 byte 타입으로 해 주어야 하기 때문이다.

 

다음은 C언어 기반의 서버에 소켓을 연결해서 한 번 메시지를 주고받는 JAVA 클라이언트의 예제 소스이다. 서버의 소스는 포함하지 않는다.

 

Example.java

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;

public class Example {

	private static final String serverIP = "1.234.56.78";	// your serverIP
	private static final int portNum = 1234;		// your port number
	private static final int buffersize = 100;

	private Socket mSocket = null;
	private DataOutputStream mObjOStream = null;
	private DataInputStream mObjIStream = null;

	public Example()
	{	
	}
	
	public static void main(String args[])
	{
		Example example = new Example();
		example.connect();
	}

	public void connect()
	{
		try
		{
			mSocket = new Socket();
			mSocket.connect(new InetSocketAddress(serverIP, portNum));
			mObjOStream = new DataOutputStream(mSocket.getOutputStream());
			mObjIStream = new DataInputStream(mSocket.getInputStream());
			System.out.println("connection successed");
			
			byte[] out = new byte[buffersize];
			String sendmgs = "kugistory.net";	// your sending message
			out = sendmgs.getBytes();
			mObjOStream.write(out);
			mObjOStream.flush();
			System.out.println("message sended: " + sendmgs);
			
			byte[] in = new byte[buffersize];
			mObjIStream.read(in,0,in.length);
			String response = new String(in,0,in.length);	// your receiving message
			response.trim();
			
			System.out.println("response=" + response + "@end");
			mSocket.close();
		}
		catch ( Exception e )
		{
			e.printStackTrace();
		}
	}
}

Posted by Kugi
,



안드로이드에서 현재 시간을 알아내기 위해서는 여러 가지 방법이 있겠지만 그 중에서 한 가지를 소개하자면

 

java.util.Calendar 오브젝트를 이용하는 것이다. java.util에 포함되어있기 때문에 물론 안드로이드 뿐만 아니라 일반 자바 프로젝트에서도 이용 가능하다.

 

다음은 사용 예시이다.

 

public static String GetCurrentTime() {
	String time = "";
	Calendar cal = Calendar.getInstance();
	time = String.format("%04d-%02d-%02d-%02d-%02d-%02d-%03d",
			cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1, cal.get(Calendar.DAY_OF_MONTH),
			cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND), cal.get(Calendar.MILLISECOND));
		
	return time;
}

 

출력되는 포맷은 편의에 맞게 고치면 된다.

이 때 cal.get(Calendar.MONTH)는 "반환값+1"이 실제 달 수이므로 주의해야 한다.

0~12까지의 값을 반환하며 이는 각각 다음과 같이 매치된다.

  0 JANUARY
  1 FEBRUARY
  2 MARCH
  3 APRIL
  4 MAY
  5 JUNE
  6 JULY
  7 AUGUST
  8 SEPTEMBER
  9 OCTOBER
 10 NOVEMBER
 11 DECEMBER
 12 UNDECIMBER

 

시간(hour)을 얻어오는 cal.get(Calendar.HOUR_OF_DAY)는 24시 표현으로 시간 값으로 반환한다.

Posted by Kugi
,



file name: HttpServerDemo.java

======================================================================================

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executors;

import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

public class HttpServerDemo {
  public static void main(String[] args) throws IOException {
    InetSocketAddress addr = new InetSocketAddress(8080);
    HttpServer server = HttpServer.create(addr, 0);

    server.createContext("/", new MyHandler());
    server.setExecutor(Executors.newCachedThreadPool());
    server.start();
    System.out.println("Server is listening on port 8080" );
  }
}

class MyHandler implements HttpHandler {
  public void handle(HttpExchange exchange) throws IOException {
    String requestMethod = exchange.getRequestMethod();
    if (requestMethod.equalsIgnoreCase("GET")) {
      Headers responseHeaders = exchange.getResponseHeaders();
      responseHeaders.set("Content-Type", "text/plain");
      exchange.sendResponseHeaders(200, 0);

      OutputStream responseBody = exchange.getResponseBody();
      Headers requestHeaders = exchange.getRequestHeaders();
      Set<String> keySet = requestHeaders.keySet();
      Iterator<String> iter = keySet.iterator();
      while (iter.hasNext()) {
        String key = iter.next();
        List values = requestHeaders.get(key);
        String s = key + " = " + values.toString() + "\n";
        responseBody.write(s.getBytes());
      }
      responseBody.close();
    }
  }
}

 


Posted by Kugi
,