펄마니아 (www.perlmania.or.kr) 게시판에 위와 같은 글이 올라와 잠시 설명을 해봅니다.

유니코드와 UTF-8은 다릅니다. 문자 코드와 문자 인코딩이 다른 것입니다.
유니코드가 왜 필요한지는 아실테니 그냥 넘어가고, 유니코드는 말 그대로 문자에 대한 코드입니다. 알파벳 'A'는 U+0x0041, 한글의 '가'는 U+0xAC00로 나타낼 수 있는데, 여기서의 'U'는 유니코드의 시작점이고, 뒤쪽의 16진수는 유니코드의 정의 테이블에서 각 문자가 어디에 위치하고 있는지를 나타냅니다. (이를 코드 포인트라고 합니다.) 이 유니코드 테이블은 정의가 완료된 상태가 아니며, 앞으로도 계속 크기가 커질 것입니다. (www.unicode.org에서 계속 작업중입니다.)

이런 식으로 현재 유니코드 표준에 포함된 문자들은 각자의 고유한 코드포인트를 가지고 있습니다. 최초에 유니코드가 나왔을때는 거의 모든 문자의 코드포인트가 2^16 범위 안에 들어와서 아스키 문자는 1바이트, 유니코드는 2바이트라는 이상한 정의가 통했지만, 지금은 꼭 그렇지는 않습니다. 중요한 것은, 유니코드는 특정 바이트의 수로 정의할 수 없는 추상적인 위치라는 거지요.

그럼 이 문자들을 실제 컴퓨터에서는 어떻게 표현하는 것이 좋을까요? 그리고 이기종 컴퓨터간에는 유니코드 문자열을 어떻게 주고받을 수 있을까요? 여기서 필요한 것이 유니코드의 인코딩 방식입니다. UTF8, UTF16, UTF16-BE, UTF16-LE, UCS2, UCS4 이런 다양한 인코딩 방식이 유니코드를 인코딩하는 데 사용되고 있습니다.

UCS2, UTF16 계열은 모든 문자를 2바이트(16비트)로 인코딩합니다. 초창기 유니코드를 프로그래밍한다 하면 대부분 이 인코딩을 생각했습니다. 그리고 C/C++에서도 wchar_t가 2 byte로 정의되어 있는 경우가 대부분입니다. 이렇게 무조건 문자를 2바이트로 표시하면, 대부분의 유럽문자, 한글, 한자, 일본어 등이 표현 가능합니다. 하지만 한글 고대어 등등... 2^16 범위를 넘어가는 코드 포인트의 문자는 표현할 수 없습니다. (A는 0x00, 0x41, 한글 '가'는 0xAC, 0x00 이런 식으로 표현하는 거죠. 이 경우에는 동아시아 문자같은 멀티바이트 문자들은 낭비가 없지만, 영문자만 사용하는 국가들에서는 첫번째 바이트를 무조건 0x00으로 맞춰야 하므로 낭비가 생깁니다.)

UCS4는 유니코드 문자를 4바이트로 인코딩합니다. 이러면 현존하는 유니코드 3.0 규약의 모든 문자를 표현할 수 있습니다만, 메모리 및 네트웍 트래픽, 데이터의 낭비가 너무 심하겠죠.

그래서 몇몇 머리 좋은 사람들이 UTF-8을 만듭니다. UTF-8은 가변길이의 인코딩으로, 모든 유니코드 문자를 표현할 수 있습니다. 대신 약간의 비트 연산이 필요합니다.

UTF-8은 U+0000부터 U+007F 까지의 문자들은 그대로 1바이트로 표기합니다. 유니코드의 정의상 이 부분은 ASCII 코드와 그대로 일치하므로, 기존 아스키 문자열도 그대로 호환됩니다.
U+007F보다 큰 코드포인트의 문자들은 그 범위에 따라 각각 2바이트, 3바이트, 4바이트로 인코딩될 수 있습니다.

다음 비트 표를 보시면 이해가 쉬우실 겁니다.

U-00000000 - U-0000007F:  0xxxxxxx (1바이트 : 대부분의 영문자)
U-00000080 - U-000007FF:  110xxxxx 10xxxxxx
U-00000800 - U-0000FFFF:  1110xxxx 10xxxxxx 10xxxxxx (3바이트 : 한글)
U-00010000 - U-001FFFFF:  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 - U-03FFFFFF:  111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 - U-7FFFFFFF:  1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

UTF-8이 가장 낭비가 없이 모든 유니코드를 표현할 수 있기 때문에, 점차 인코딩 표준이 될 것이라 생각됩니다. (영어만 사용한다면 이게 최고죠...) 한글은 현대 한글기준으로 보면 대부분 UTF-8 인코딩으로 3바이트로 표현됩니다. UCS2보다는 1바이트 더 쓰지만 어디 한글만 쓸일 있나요~

설명하는 재주가 없어서 다소 장황합니다만, 명랑 유니코드 세상이 오기를 기원하며 몇 자 적어보았습니다. 도움이 되셨길 바랍니다~

Posted by leigh
포스팅이 좀 뜸했습니다.

블랙베리 프로젝트 때문에 시간이 좀 부족해서 :)

사실 프로젝트는 그닥 범위가 넓은 편은 아니었는데, 생소한 플랫폼에 적응하기도 조금 힘들고 빈약한 도큐먼테이션 때문에 실험이 많아서 시간이 많이 걸리더군요.

사실 블랙베리 디벨로퍼 가이드는 문서의 양도 비교적 많고 읽기도 편하지만, 운영체제의 코드를 볼 수 없기 때문에 어떤게 되고 어떤게 안되는지 알기가 쉽지 않았습니다. 이런 면에서는 Microsoft  사와 비교가 안될 수가 없더군요. Microsoft 사도 오픈이 아닌 운영체제를 개발플랫폼으로 사용하고 있지만, 그렇기 때문에 오히려 문서와 샘플에 대해서는 타의추종을 불허할 정도로 막강한 라인업을 구축하고 있습니다.

무엇보다 문제가 된 것은 플랫폼의 버그였습니다. 도큐먼트에 기록된 API의 일부가 문서와는 다르게 이상 동작을 하더군요. 하필이면 그 API들이 제가 구현해야 하는 기능들의 핵심이 되는 부분에 위치한다는 것이 문제였습니다. 제가 코드를 잘못 쓴 줄 알고 몇날 며칠을 고민했었거든요. RIM 사에 짧은 영어로 증상을 설명하니, 몇몇가지들은 OS의 버그로 밝혀졌습니다.

사실 이 정도의 시스템에 그 정도의 버그라면 충분히 이해할 만합니다. 그렇지만, 애초에 API 가이드를 읽고서 충분히 구현 가능하다고 생각한 기능들이 실제로 제대로 동작하지 않기 때문에 명세에서 빠져야 하는 것을 보니 아쉬움을 감추기가 힘드네요.

나중에 저처럼 고생하시는 분들이 혹시 있을 지 몰라 RIM에서 버그로 확인받은 두가지를 알려드리겠습니다. (참고로, 개발환경은 JDE 4.1입니다. 이후 릴리즈에서는 버그가 잡혔을 수 있습니다.)

1.  7100/8100 모델에서는 BasicEditField의 setEditable 메소드가 정상동작하지 않을 수 있습니다.
즉, isEditable()이 true를 리턴하더라도, 문자가 입력되지 않는 버그가 있습니다.

2. RepeatRule의 DAY_IN_WEEK 속성을 세팅하는데 버그가 있습니다. 매달 첫번째 일요일 같은 반복 일정은 세팅할 수 없습니다. (물론, 블랙베리 기본 캘린더 프로그램으로는 세팅할 수 있습니다. -_-)

이제 고민은 그만 하고 프로젝트 얼른 마무리해야겠습니다~
Posted by leigh
블랙베리 OS에서 기본으로 KSC5601 인코딩을 지원하지 않기 때문에, 간단한 코드 변환 클래스를 작성할 요량으로, KSC5601과 유니코드가 매핑된 char 테이블을 static 배열로 잡았습니다.

private static final char [] CODEMAP = {
   0x3000,0x3001,0x3002,0x00B7....
};

그런데 컴파일을 하려고 보니, static initializer가 65535 바이트를 초과했다면서 컴파일이 되지 않더군요.
깜짝 놀랐습니다. 배열 크기가 좀 크다고 컴파일이 안된다니... C/C++, C#에서는 이런 경험을 해본 적이 없었거든요.

여기저기 지인들한테 물어보고, 구글의 도움도 받아서 몇가지 실험을 해보았습니다.

1. 테이블을 파일에 기록하고, 클래스를 생성할 때 파일에서 읽어들여 초기화한다.
   가장 좋은 방법입니다. 하지만, 사용하고 있는 OS가 파일시스템을 지원하지 않거나 파일을 읽기가 복잡한 경우에는 좀 문제가 있겠죠? 그리고 static 초기화된 배열에 비해서 초기화시간도 오래 걸릴 수 있습니다.

2. 배열을 몇 구역으로 나눠본다.
  예를 들어, 1000개씩 배열을 나눠서 static 배열을 여러개 생성하는 것인데, 역시 안되더군요. 자바가 멤버들을 static 초기화할 때 아마 하나로 합쳐서 생성하도록 컴파일하는 모양입니다.

3. static 초기화를 사용하지 않고, 생성자에서 직접 하나씩 값을 넣는다.
   생성자에서 new char[MAX_RECORDS]를 한 다음에, 하나씩 값을 배열에 대입하여 초기화해 봤습니다.

class Dummy {
   private char[] map;
   public Dummy {
       map = new char[8000];
       map[0] = 0x3000;
       map[1] = 0x3001;
       ....
   }
}

   생성자에도 65535 바이트 제한이 걸려있어서 실패했습니다. 생성자가 아닌 일반 메소드로 만들어봤지만 역시 안되더군요. 일반 메소드의 코드 크기도 65535 바이트를 초과할 수 없습니다.

4. 초기화 함수를 여러개로 나눠서 생성자에서 부른다.
   배열을 초기화하는 함수를 65535 바이트가 넘지 않게 여러개로 나눠서 만드는 방법을 실험해 봤습니다.
즉, 배열요소를 1000개씩 초기화하는 함수를 8-9개 만들어서 생성자에서 한꺼번에 호출해 봅니다.

class Dummy {
   private char[] map = new char[8000];
   public Dummy {
       init1();
       init2();
       ....
   }
   private void init1() {
       map[0] = 0x3000;
       map[1] = 0x3001;
       ...
   }
   private void init2() {
       map[0] = 0x300D;
       map[1] = 0x300E;
       ...
   }
   ...
}

오호라~ 이 코드는 컴파일이 됩니다. 일반적인 환경에서는 거대 배열이 있을 경우 이런 식으로 초기화해서 사용하면 될 듯 싶습니다.

그렇지만.... 블랙베리 JDE에서 저렇게 작성된 클래스를 컴파일하려고 했더니, 또 컴파일 에러가 나더군요.
이유는, 생성된 바이트코드가 너무 크다는 것이었습니다. 블랙베리에서 돌아가는 실행파일은 .cod라는 확장자를 가지는데, 이 .cod 파일의 크기 제한 (공식적으로 64K)이 있었습니다. 아쉬운 순간~

5. 배열을 조각조각내고 각각 클래스로 감싼다.
   4번까지 실패하고서, 이제 자바 내부 소스를 보던지 아니면 파일을 이용해야겠다... 하고 생각하던 순간, 이렇게해보면 어떨까 하는 생각이 났습니다.
   먼저 배열을 담을 클래스들을 생성하고 배열을 1000개씩으로 잘라서 각각 static 멤버로 선언해 주었습니다. 이렇게 하면 static initializer의 크기 제한에 걸리지 않게 됩니다.

// 1000개씩 잘라서 클래스로 다 만듭니다.
class Table1 {
   public static char[] table = {
       0x3000,0x3001....
   }
}
class Table2 {
   public static char[] table = {
       0x300D,0x300E....
   }
}

   실제 배열을 사용할 경우에는 배열 인덱스의 구간을 조사한 다음에 알맞은 클래스의 static table 필드를 다시조회해야 되는 귀찮음이 있습니다만, 어쨌든 저런 방법으로도 큰 배열을 코드 상에서 static으로 초기화할 수 있습니다.
   cod 파일의 크기 제한은 어떻게 됐을까요? 4번 방법의 1/5로 줄어들더군요. 똑같은 크기의 배열을 선언한 것이지만,4번의 경우에는 일일히 하나씩 대입해주기 때문에, static으로 초기화하는 5번 코드보다 코드 사이즈가 많이 커졌던 것이죠.

  성공!!!! 몇 시간의 실험을 거친 끝에 어쨌든 간단한 코드 변환 클래스를 테스트할 수 있었답니다~

이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by leigh

ESS란?

블랙베리 시뮬레이터에서도 이메일 보내기/받기 기능을 테스트해볼 수 있습니다. 통합 개발 환경 JDE를 설치하면 따라오는 ESS (Email Server Simulator) 를 이용하면 블랙베리 단말기 시뮬레이터로도 이메일을 보내고 받을 수 있습니다.

RIM사에서 제공하는 공식 문서인 "BlackBerry Application Developer Guide - Volume 1"의 "Test and debugging" 섹션에 잘 소개되어 있습니다만, 한글로 사용법을 간단히 적어보겠습니다.

ESS 설정 및 구동

1. 시작 프로그램 -> 모든 프로그램 -> Research In Motion -> BlackBerry JDE 4.1.0 -> ESS 를 실행합니다. 이 때, NoClassDefFoundError 에러를 내면서 실행이 안될 수 있습니다. 이런 경우에는 시스템 환경변수의 CLASSPATH가 잘못 설정되어 있을 가능성이 큽니다. 환경변수를 올바로 맞추던지, 아니면 CLASSPATH 환경변수를 아예 삭제하시면 됩니다.

2. Email Server Simulator 폼이 뜹니다. 이 폼에서 ESS의 작동 모드 및 기타 설정 사항을 설정해줍니다.

3. ESS의 실행 모드를 선택합니다.

3.1. Standalone Mode로 선택

Standalone Mode는 ESS가 단독으로 이메일 보내기/받기 모든 기능을 알아서 처리하는 모드입니다. 기존에 사용하는 메일 서버가 없거나, POP3/SMTP를 지원하지 않으면 이 모드를 사용하세요. 저는 사용가능한 메일 서버가 몇대 있지만 그냥 간편히 이 모드로 테스트 중입니다.

3.1.1. Standalone Mode 라디오 박스를 선택합니다.
3.1.2. 기존의 저장된 시뮬레이터 메일 메시지들을 지우려면 Clean FS 버튼을 눌러줍니다. ESS는 standalone mode 일 경우 메일 메시지를 사용자의 하드디스크에 저장하게 됩니다.

3.2. Connected Mode로 선택

Connected Mode는 ESS가 지정된 메일 서버와 통신하면서 메일을 송/수신합니다. SMTP와 POP3를 지원하는 메일 서버가 있어야 합니다.

3.2.1. Connected Mode 라디오박스를 선택합니다.

3.2.2. 설정 사항을 입력합니다. Outgoing에는 메일을 보낼 때 사용할 서버의 주소를, Incoming에는 메일을 받을 때 사용할 서버의 주소를 넣습니다. User name과 Password는 SMTP및 POP3 서버에 접속할 때 사용할 계정 정보를 입력하시면 됩니다.

3.2.3. "Poll inbox... " 항목에 메일이 왔는지를 확인할 시간 간격을 지정합니다. 메일 푸시 기능을 시뮬레이션하기 위해서, ESS는 Connected Mode일 경우 지정된 시간이 지날 때마다 POP3 서버에 접속하여 메일을 확인합니다.

4. 폼 하단의 Name, Email을 채웁니다. 이 항목은 블랙베리 단말기 시뮬레이터의 메일 주소 및 표시 이름을 설정합니다. test@bbdevice.com 정도로 사용하면 기억하기 쉬울까요? PIN (Personal Identification Number)는 그냥 "2100000A"로 놔둡니다.

6. Launch 버튼을 눌러 계속 진행합니다. 이때, 콘솔화면으로 에러가 출력될 수도 있으니 확인해 보세요.

시뮬레이터에서 메일 보내기

1. ESS가 떠있는 상태에서 블랙베리 단말기 시뮬레이터를 켭니다.

2. Message 프로그램을 구동시키고, Compose Email 기능을 선택합니다.

3. Standalone 모드로 ESS가 실행된 경우, To:에 아무 email 주소나 넣으셔도 됩니다. Connected Mode인 경우, 서버에서 확인이 가능한 메일 주소로 메일을 보냅니다.

시뮬레이터에서 온 메일 확인하기

1. ESS가 떠있는 상태에서 일반적인 메일 클라이언트 프로그램을 켭니다. (SMTP 및 POP3를 지원하는 프로그램이면 아무거나 상관없습니다. 저는 실제 메일 클라이언트로는 Outlook을 사용하지만, 시뮬레이터 테스트를 위해서는 Outlook Express를 사용하고 있습니다.)

2. Standalone 모드인 경우, 확인할 메일 계정을 추가합니다. 이 때, 보내는 서버 및 받는 서버를 모두 "localhost"로 지정합니다. 사용자 계정 및 암호는 아무거나 사용합니다. (어짜피 체크도 안합니다.)

3. Connected 모드인 경우, ESS에 지정한 메일 서버 및 계정 정보를 그대로 사용합니다.

4. 메일이 왔는지 확인해 봅니다.

시뮬레이터로 메일 보내기

1. ESS가 떠있는 상태에서, 메일 확인할 때와 동일한 설정으로 된 메일 클라이언트를 엽니다.

2. ESS에서 지정한 단말기 시뮬레이터의 메일 주소로 메일을 쓰고 보냅니다. (test@bbdevice.com 이었나요?)

3. 단말기 시뮬레이터의 Messages에 메일이 도착했는지 확인합니다.

마치며

이상으로 ESS를 통해 시뮬레이터에서 메일 송/수신을 테스트하는 방법을 알아보았습니다.

RIM사에서 개발자들이 이메일 기능을 쉽게 테스트할 수 있도록 신경을 쓴 티가 좀 나죠? 이 정도면 메일을 보내고 받는 기능을 테스트하는데에는 큰 무리가 없을 듯 합니다. 블랙베리 서비스가 푸시 메일 서비스로 인기를 얻은 만큼, 이 기능이 사실 서비스의 핵심이라고 볼 수 있겠죠?

PS) 한글로 작성한 메일은 시뮬레이터에서 읽을 수가 없습니다. 시뮬레이터로 보내는 한글 메시지를 ks_5601 혹은 UTF-8로 인코딩해 보아도 마찬가지로 깨져서 보이네요. 실제 정식 블랙베리 푸시 메일 서버를 통해서 받은 메일의 경우에는 아직 확인해보지 못했습니다만, 관계자들의 전언으로는 그러한 경우에는 한글이 보인다고 합니다.

이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by leigh

RIM사에서 제공하는 JDE (통합 개발 환경) 과 함께 배포되는 시뮬레이터로 블랙베리 단말기용 애플리케이션을 개발할 수 있는데, 이 시뮬레이터에서 한글을 보는 방법입니다.

기본으로 깔리는 시뮬레이터에는 한글이 설정되어 있지 않은데, 간단한 xml 편집으로 한글 폰트 및 한글 읽기 기능을 설정할 수 있습니다.

1. 먼저, JDE가 설치된 폴더로 갑니다. 제 컴에서는 다음과 같습니다.
C:\Program Files\Research In Motion\BlackBerry JDE 4.1.0\simulator

2, 사용하고자 하는 모델의 시뮬레이터 xml을 텍스트 편집기로 엽니다.
7100g 모델을 사용하고자 한다면 7100g.xml 파일을 열면 됩니다.

3. <SimulatorConfigruation> 노드에 다음 노드를 추가합니다.
  <Application>net.rim.blackberry.lang.korean</Application>

4. xml을 저장하고 다시 시뮬레이터를 구동시킵니다.

일본어를 보고 싶으면 net.rim.blackberry.lang.japanese도 추가해주면 됩니다.
단, 한글과 일본어는 볼 수만 있고 입력은 안된답니다. :)

이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by leigh

블랙베리

2006/08/11 18:10
어쩌다보니, 이번에 한국에는 처음 들어온 블랙베리 (Blackberry) 단말기에서 작동하는 애플리케이션을 개발하게 되었습니다. 자세한 사항은 뭐 회사에 묶인 몸이라 이야기할 수가 없지만...

시뮬레이터로 이것저것 관찰해보니, 단말기와 OS 자체는 꽤 심플하고 사용하기 좋게 만들어져 있는 것 같네요. 터치스크린을 지원하지 않는 대신, 트랙휠이라는 꽤나 편리한 네비게이션 도구를 제공하고, Qwerty 자판 배열을 그대로 가지고 영문 입력을 하는 것도 편리합니다. 이번에 런칭한 7100i 모델은 변형 Qwerty 자판이지만, SuteType이라는 사전 기반의 자동 correction 기능이 들어있어서 영문의 경우에는 큰 불편없이 입력이 가능합니다. (불행히도, 아직 한글 입력은 되지 않습니다.....)

OS는 터치스크린을 기본으로 사용하는 Pocket PC와 비교할 수는 없지만, 꽤나 이쁘고 편리하게 만들어져 있습니다. 아이콘도 큼직큼직한 것이 X윈도나 애플에서 봄직한 스타일이랍니다. 이메일 열람/작성이 가능하고 (사실 이메일 푸시 기능 때문에 블랙베리가 유명해진 것이지만), Organizer도 그런대로 사용하기 편하게 되어 있습니다. JVM 기반 OS라 간단한 프로그램을 만들어 넣는 것도 그리 어렵지는 않은 듯 하고요.

그래도, 개발환경을 접해보니 Pocket PC Visual Studio.NET 2005를 사용하던 때가 그리워질 것 같네요. C# 언어와 폼디자이너로 슥슥하면 폼 개발이 금방이었는데 T_T

에구구, 앞으로 영어 문서들과 씨름할 일이 태산이겠지요 :)

PS) 블랙베리 단말기 환경에서의 개발에 관심이 있으신 분들은 http://www.blackberry.com/developers/index.shtml 를 방문해 보면 정보를 많이 얻을 수 있습니다.
이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by leigh

Programming Pearls

2006/03/31 13:38

Wizz군의 블로그에서 신입사원 면접 문제에 대한 포스트를 읽었습니다.

사실 저 문제는, Jon Bently의 유명한 "Programming Pearls" (번역서 제목은 "생각하는 프로그래밍" 입니다.) 의 첫번째 예제로 나오는 정수 파일 정렬하기의 거꾸로 버전입니다.

"1부터 27000 사이의 번호가 1번씩만 존재하는 파일이 있는데, 이 파일을 정렬하라. (단 파일에서 번호는 1번씩만 출현하고, 총 번호의 개수는 27000보다 작을 수 있다. 단, 프로그램이 돌아가는 환경에서 가용한 메모리는 수KB 안쪽으로 매우 작고, 거대 시스템의 하위 시스템으로 작동하는 모듈이라서 속도도 매우 빨라야 한다."

이 정도의 요구사항을 만족하는 코드를 작성하는 문제였죠. 책에는 Pseudo Code로 작성된 알고리즘이 소개되어 있습니다.

처음 저 책을 읽고서는 첫번째 예제가 너무 마음에 들어서 집에 가서 바로 작성해 봤던 기억이 있습니다.

얼마전에 신입사원 입사 문제로 출제하면서 다시 한번 짜봤는데, C++을 사용하면 매우 간단하게 만들 수 있습니다. bitset 컨테이너가 bitmap 자료구조를 손쉽게 구현하게 해주거든요. C로 하려면 약간 귀찮게 비트를 조작하는 매크로나 함수를 작성해야 합니다.

코드 보기..

반대로, Wizz 군의 블로그 내용을 만족하는 코드는 위의 예제를 좀 뒤집으면 되겠죠?
저장 공간을 아끼기 위해서 bitset 컨테이너를 사용했습니다.

코드 보기..


Wizz 군처럼 shuffle로 정해진 반복 회수를 보장하려면, random_shuffle을 사용하면 됩니다.

코드 보기..


Programming Pearls, 1980년대에 출판되었지만, 지금도 정말 읽을만 합니다.
이번 주말에 다시 한번 읽어봐야겠네요.
이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by leigh

요새 Pocket PC 플랫폼에서 C++로 서버/클라이언트 네트워크 프로그램을 개발하고 있습니다. 와이브로가 상용화되면, PDA 플랫폼에서도 꽤 많은 애플리케이션이 개발될 것 같아요. 플랫폼에 익숙하지 않아서 엄청 삽질을 하고 있는데, Pocket PC 네트워크 프로그램 개발 및 테스트 환경에 대해 몇 가지 새로 알게 된 것을 적어 보겠습니다.

1. MFC의 소켓 클래스는 사용하지 말자.

Windows CE 플랫폼에서는 절대 MFC의 CSocket이나 CAsyncSocket은 사용하지 마세요. PC기반에서도 사용해선 안될 악의 축인 놈들입니다. 특히 CE에서는 오동작이 많습니다. 연결할 서버가 죽어있는 경우에도 Connect 함수가 TRUE를 반환하는 아~주 악질인 넘들이니 절대 쓰지 마세요. 그냥 윈속 2.0에 정의되어 있는 기본 소켓 함수들을 가지고 작업하시는 것이 1000배 맘 편합니다.

2. ActiveSync 상에서의 PC와 Pocket PC 주소

일반적으로 Pocket PC에서 돌아가는 프로그램을 개발한다고 하면, Visual Studio.NET이나 Embedded Visual C++을 이용하여 소스 편집 및 컴파일은 데스크톱 PC에서 하고, 바이너리만 포켓 PC로 배포하여 테스트를 하게 됩니다. 바이너리 배포를 하려면 ActiveSync를 사용해야 하는데, ActiveSync상태에서는 PC를 통해 인터넷으로 연결됩니다. PC가 공유기처럼 작동하게 되지요.

PC쪽에 TCP 클라이언트를 만들고, Pocket PC에서 PC쪽으로 접속하는 거라면, 별 문제가 없습니다. Pocket PC 클라이언트에서는 데스크톱 PC의 IP만 제대로 지정하여 connect하면 됩니다. 굳이 WiFi로 연결되어 있지 않아도, ActiveSync를 통해서 PC쪽 서버에 접속할 수 있습니다.

만약, 데스크톱 PC가 인터넷에 연결되어 있지 않다면? 이러면 조금 문제가 되는데, 데스크톱 IP를 이용하여 Pocket PC가 PC에 연결할 수 없습니다. 외부에 데모를 나가서 개발 현황을 보여줘야 하는데, 프리젠테이션 환경이 열악하여 네트워킹이 안된다면 꽤나 난감하지 않을 수 없죠. 이런 경우 PC에 만들어 둔 서버에 접속하기 위해 'localhost'나 루프백 IP(127.0.0.1)을 사용하려고 하는 경우가 많은데, 요거 잘 작동하지 않습니다.

그럴 땐, Pocket PC에서 PC로 접속할 때 "192.168.55.100" IP를 사용하면 됩니다. ActiveSync로 PC와 Pocket PC가 연결되면 PC는 "192.168.55.100", Pocket PC는 "192.168.55.101" IP를 사용하게 됩니다. 데스크톱 PC에 웹서버가 설치되어 있고, Pocket PC에서 PC의 웹 컨텐츠에 접근해야 한다고 할때도 마찬가지로 http://192.168.55.100/contents.html 요런 식으로 URL을 쓰면 된답니다.

3. ActiveSync 상에서 PC에서 PDA로 접속하기

이제 PC가 서버가 아니라 Pocket PC가 서버가 되는 상황입니다. Wi-Fi로 연결된 상태라면, PC쪽이 서버일 때와 마찬가지로 그냥 Pocket PC쪽 IP로 접속하면 됩니다. 무선 AP와 무선 네트워크 카드, 그리고 TCP/IP 스택과 socket API가 알아서 다 해주겠죠?

하지만, 개발 중에는 Wi-Fi를 쓰는 게 매우 귀찮습니다. 소스를 컴파일해서 디바이스에 넣으려면 어짜피 ActiveSync를 사용해야 하기 때문이죠. 위에서도 썼지만, ActiveSync로 연결된 상태에서는 Wi-Fi는 무용지물이거든요. 무선 네트워크 카드에 배당해 둔 IP가 전혀 작동하지 않습니다. 그 IP로 접속해봐야 접속이 안됩니다. 컴파일 바이너리를 배포한 후 제대로 작동하는 지 테스트하려고 이제 디바이스를 크래들에서 빼내야 합니다. 문제가 생기면 또 크래들에 꽂은 후 다시 컴파일 배포... 크래들에서 빼서 또 테스트... 아 귀찮습니다. 게다가, 크래들에서 빼놓으면 EVC나 VS.NET에서 디버깅도 할 수 없죠. (전 개발용 보드로 개발해 본 적은 없어서, 뭐 시리얼 콘솔로 출력하면 되지 않냐 이런 말씀을 하셔도 이해 못합니다.)

아하~ 여기서 눈치 빠르신 분들은, 그럼 ActiveSync의 Pocket PC쪽 IP인 "192.168.55.101"로 접속하면 되지 않겠냐? 하시네요. 짝짝짝... 하지만 안됩니다. 여러번 시도해봤지만 안되더군요. 구글 친구들 (groups.google.com) 한테도 많이 물어봤지만, 시원스레 대답해주는 포스트는 없었습니다. 그래도 뉴스 그룹을 뒤지고 뒤져서 알아냈습니다. ActiveSync 상에서 PC -> Pocket PC로 접속할 땐 "127.0.0.1"을 써야합니다! 아하하....

자  이제 거의 다 됐습니다. "127.0.0.1"로 접속하고, 포트는 음... 한 20000 정도 해볼까요? Pocket PC 서버는 INADDR_ANY, 20000 포트에 바인딩하고 귀기울여 PC 클라이언트가 붙기를 기다립니다. 자 PC 클라이언트를 기동하고 connect 해봅시다... 음... 안됩니다, 안돼요 T_T

ActiveSync 상에서 PC -> PDA로 TCP 접속을 하려면, 이놈의 ActiveSync에 내가 몇번 포트를 proxy port로 사용할 것인지를 알려줘야 한다는군요. 잠시 짜증을 접어두고, regedit를 실행시켜봅시다. "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows CE Services\ProxyPorts" 항목을 찾아보세요. ActiveSync가 Pocket PC와 통신할 때 사용하는 포트가 주르륵 리스팅되어 있습니다.

DWORD 값을 하나 만들고 이름을 "MyPort" 쯤으로 넣습니다. 값은 20000 (10진수로) 넣으면 되겠죠? 이제 다 끝났습니다. 레지스트리 에디터를 닫고, Pocket PC와 PC 프로그램을 작동시켜 봅니다. 접속돼라 돼라 돼라~ 오!!!! 이제 되는군요.

4. 맺으며

Pocket PC 플랫폼은 WIN32 시스템과 거의 동일해서, 개발 장벽이 낮은 편이랍니다. Windows 프로그래밍을 조금 경험해보신 분이라면, 큰 이질감없이 프로그램 개발을 하실 수 있죠. 그렇지만 Windows와 Windows CE는 역시 다른 운영체제라서 조금씩 차이가 나는 건 어쩔 수가 없나봅니다.

오늘 적은 팁들은 사실 별거 아닌건데, 딱히 알고 싶어도 금방 찾을 수가 없더군요. 아무쪼록 혹시나 제 글을 읽으신 분들이 조금이라도 도움이 되셨기를 바랍니다.

이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by leigh

첫 글

2006/03/24 13:33

2년 전까지 blogin의 서비스를 이용하다가, 이제 새로 시작해볼까 합니다.

아무래도 일을 하면서 알게 된 소소한 것들을 기록하고 공유해 둘 공간이 필요하기도 하고, 글쓰는 연습도 해야 할 것 같아서요.

처음 블로깅을 시작했을 때는 너무나 낯선 개념이라서 일기장이랑 혼동하기도 하고, 펀글로 도배를 하기도 했었는데, 이제는 그런 것들은 좀 지양해야겠지요.

이 블로그가 앞으로도 제 삶에 있어서 유익하고 즐거운 공간이 되기를 기원해 봅니다.

이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by leigh

BLOG main image
by leigh

공지사항

카테고리

분류 전체보기 (9)
블랙베리 (5)

최근에 받은 트랙백

Total : 33,236
Today : 0 Yesterday : 8