'분류 전체보기'에 해당되는 글 22건
- 2013.03.23 [번역] A-Z of Programming Languages: Scala 1
- 2011.01.30 [삽질記] luabind를 사용하여 루아에서 C++ 코드 호출하기
- 2009.02.21 리눅스에서 mbc 라디오 온에어 듣기 2
- 2009.01.04 [리눅스 라디오 프로그램 제작기] 2. kbs 온에어 재생 7
- 2009.01.04 [리눅스 라디오 프로그램 제작기] 1. 개요 & 개발 환경 구축 2
- 2008.12.18 리눅스/파이어폭스로 kbs 온에어 듣기
- 2008.12.14 리눅스 비프음 끄기
- 2008.12.14 Fedora Core 6 한글 환경 설정하기 1
- 2008.12.14 mysql 기초
- 2008.12.14 [Qt] 어플리케이션 다국어 지원
[번역] A-Z of Programming Languages: Scala
원문 : http://www.computerworld.com.au/article/315254/a-z_programming_languages_scala/
트위터와 링크드인 모두 스칼라를 사용하지만, 웹 2.0 스타트업들의 총아인 스칼라는 대기업에서도 널리 사용된다. 컴퓨터월드는 마틴 오더스키와 얘기를 나눴다.
컴퓨터월드는 프로그래밍 언어 세계로의 연속된 조사를 하고 있다. 이미 해스켈, 얼랭, (역시 JVM 에서 실행되는) 클로저 등의 몇 가지 다른 함수형 언어를 살펴보았다.
이번 인터뷰에서는 마틴 오더스키와 스칼라에 관해 이야기했다. 우리는 스칼라를 개발자들이 써봤으면 하는 6가지 스크립트 언어 중 하나로 꼽은 바 있다. 스칼라는 자바 가상 머신에서 돌아가는 새로운 언어 중 하나이며, 점점 인기를 얻고 있다.
트위터 개발자 중 한 명은 스칼라가 그 새로운 웹 2.0 스타트업의 선택 받은 언어가 될 수 있다고 말했다. 링크드인 또한 스칼라를 쓴다. 소니 픽쳐스, EDF, SAP을 비롯한 많은 대기업에서도 사용한다. 마틴 오더스키는 스칼라의 역사, 미래, 그리고 무엇이 스칼라를 매우 흥미롭게 만들었는지에 관해 얘기해줬다.
왜 이름을 스칼라라고 지었나?
아주 작게 시작하지만 먼 길을 갈 수 있다는 점에서 확장 가능한scalable 언어라는 뜻이다. 새로 접한 사람들에게는 스크립트 언어처럼 보인다. 실제로 지난 2년 동안 자바 스크립트 언어 시합인 JavaOne ScriptBowl에서 경쟁하도록 초대를 받기도 했다. 그러나 스칼라는 진짜로 스크립트 언어는 아니다 - 그것은 스칼라의 주요 특성이 아니다. 사실, 스칼라는 자바로 할 수 있는 모든 것을 표현할 수 있고, 자바의 능력을 넘어서 대규모 시스템에 필요한 많은 것들을 스칼라가 제공할 수 있다고 믿는다. 설계 기준 중 하나는 매우 작은 프로그램에서부터 시작해서 거대한 시스템에 이르기까지 모두 유용하고, 그 과정에서 구조를 바꿀 필요가 없는 언어를 만들고 싶다는 것이었다.
무엇때문에 스칼라를 개발하게 되었나?
90년대 중반에 자바 언어와 컴파일러 개발에 참여하게 됐다. 필립 와들러라는 연구원과 함께 일하게 되었고, 우리는 나중에 제너릭 자바(GJ)가 되고 그 후 자바 버전 5가 된 피자를 개발했다. 도중에 나는 javac 컴파일러를 작성했다. GJ를 위한 그 컴파일러는, 우리의 확장판이었는데, 선이 GJ 언어 구성물을 자바에 채택하기로 결정하기 오래 전에 표준으로 채택되었다 - 컴파일러를 먼저 채택한 것이다.
10년 전에 스위스로 옮겼을 때, 더 기본적인 주제들을 연구하기 시작했다. 함수형 프로그래밍과 객체 지향 프로그래밍을 유용하게 조합할 수 있을지를 확인하기 위해 몇 가지 실험적인 연구를 했다. 95,6년에 피자로도 이미 해봤지만, 그건 절반의 성공이었다. 왜냐하면 다음어지지 않은 부분이 많았기 때문인데, 모두 그 당시에 자바를 기본 언어로 사용한 것과 관련이 있었다. 자바는 그리 변경하기 쉽지 않았다. 그래서 2000년 경부터 시작해서 EPFL(국립 로잔 공과대학)에 있는 내 그룹과 함께, 자바와 함께 쓸 수 있으면서도 객체 지향과 함수형 언어 테크닉을 유용하게 섞어 쓸 수 있는 언어를 개발했다.
이 중 첫번째는 Funnel이라 불렀고, 두번째가 스칼라였다. 두번째 실험은 아주 잘 돼서, 실험 단계는 접고 스칼라를 사람들이 기댈 수 있는 실제 언어로 만들기로 했다. 거친 면을 좀 다듬고, 문법을 약간 바꾸고, 스칼라와 스칼라 툴이 널리 쓰일 수 있다는 것을 확신하기 위해서 스칼라 툴을 스칼라로 다시 작성했다. 그 후 2006년에 스칼라 버전 2를 출시했다. 스칼라는 그 때부터 급속하게 인기를 얻고 있다.
객체 지향과 함수형 언어 테크닉을 결합하는 주요 이점은 뭔가?
둘 다 많은 것을 제공한다. 함수형 언어는 강력한 조합을 제공하기 때문에 간단한 부분들을 가지고 흥미로운 것들을 만들 수 있다 - 함수들은 프로그램의 요소들을 흥미로운 방법으로 다른 요소들과 결합한다. 이와 관련된 함수형 프로그래밍의 이점은 함수들을 데이터로 간주할 수 있다는 점이다. 거의 모든 프로그래밍 언어의 전형적인 데이터 타입은 "정수형int"이다. 정수형 값은 함수 내부를 포함한 어디에서도 선언할 수 있고, 그것을 함수로 넘기고, 함수로부터 리턴하거나 필드에 저장할 수도 있다. 함수형 언어에서는 함수에 대해서도 똑같이 할 수 있다. 함수를 다른 함수 내에서 선언하고, 함수를 함수로 넘기거나 리턴 받을 수도 있고 필드에도 저장할 수 있다. 이런 특성은 여러분 자신의 제어 구조를 만드는 데, 매우 고수준의 라이브러리를 정의하거나 새로운 DSL 만드는 데 강력한 방법을 제공한다.
반면, 객체 지향 프로그래밍은 시스템 컴포넌트를 구조화하고 복잡한 시스템을 확장하거나 개선하는 데 강력한 방법들을 제공한다. 상속과 조합aggregation은 네임스페이스를 만들고 조직화하기 위한 유연한 방법을 제공한다. IDE(통합 개발 환경)에서 어떤 지점에서 호출할 수 있는 모든 메서드를 팝업 메뉴로 제공하는 컨텍스트 도움과 같은 유용한 툴 지원이 있다.
두 가지 언어가 각각 존재하는 듯한 느낌을 주지 않고 하나의 언어로 결합하는 게 어려운 일이었다.
그 도전의 가장 중요한 부분이 무엇을 뺄 것인지를 결정하는 것이었을 것 같은데?
맞다. 만약 각 언어의 스타일을 모두 가져와 결합했다면, 중복된 점이 많아졌을 것이고 단지 서로 영향이 거의 없는 두 개의 서브 언어가 됐을 것이다. 한 쪽의 구성물을 다른쪽의 구성물과 동일시하는 게 어려운 점이었다. 예를 들어, 함수형 프로그래밍 언어의 함수값function value는 객체 지향 언어의 객체에 해당한다. 근본적으로 그것을 "apply" 메서드가 있는 객체라고 볼 수 있다. 결과적으로 우리는 함수값을 객체로 모델링할 수 있었다.
또다른 예는 함수형 언어의 대수algebraic 데이터 타입들을 객체 지향 언어에서는 클래스 계층으로 모델링될 수 있다는 것이다. 또한, 자바에 있는 스태틱 필드와 메서드를 제거하고 대신 싱글턴 객체의 멤버로 모델링했다. 그 외에도 한 언어의 구성물을 다른 언어에 존재하는 것과 매칭시켜서 합친 경우가 많이 있다.
스칼라를 개발하면서 맞닥뜨린 전체적으로 가장 큰 도전은 뭐였나?
컴파일러 기술을 개발하는 것이 확실히 어려웠다. 흥미롭게도 그 어려움은 객체 지향 언어에서보다 더했다. 진보된advanced 스태틱 타입 시스템을 갖춘 객체 지향 언어는 매우 드물었고, 그들 중에 하나도 주류가 아니었다. 스칼라는 자바나 비슷한 언어보다 훨씬 더 표현적인expressive 타입 시스템을 갖고 있어서, 구성 요소 조합을 위해 우아한 타입 개념과 프로그래밍 관념abstraction을 개발함으로써 새로운 영역을 개척break new ground해야 했다. 이것은 매우 어려운 작업이 되었고 또한 새로운 연구 결과도 나왔다.
또다른 어려운 부분은 상호 운용성interoperability과 관계가 있었다. 우리는 상호 운용이 매우 잘 되기를 원했고, 따라서 자바의 모든 것을 스칼라로 매핑해야 했다. 자바 라이브러리의 거대한 부분을 충실하게 매핑하기를 원했던 것과, 동시에 자바 언어의 모든 구성물과 중복을 피하는 것 사이에 항상 긴장이 있었다. 그것은 지속적이고 도전적인 엔지니어링 문제였다. 전체적으로 그 결과에 매우 만족하지만, 할 일이 참 많았다.
포럼에 스칼라의 효율성과 확장성에 대해 긍정적인 평가도 많지만, 자주 언급되는 다른 점은 매우 재미있게 쓸 수 있는 언어라는 것이다. 이것도 스칼라를 설계할 때의 목표 중 하나였나?
물론이다. 동료들과 나는 코드를 작성하느라 많은 시간을 보내서 즐겁게 프로그래밍할 수 있는 것을 원했다. 그건 아주 분명한 목표였다. 우리는 규약이 많은high-protocol 전통적인 언어에 있는 상투적인 것들incantations을 가능하면 많이 없애기를 원했고, 개발자들이 원하는 대로 모델링할 수 있도록 스칼라에 높은 표현력을 주고 싶었다. javac를 개발할 때 자바 프로그래밍을 많이 했는데 자바 프로그래머들이 얼마나 쓸데 없는 작업을 많이 해야 하는지를 깨달았다. 같은 프로그램을 스칼라로 개발하면 라인 수가 대체로 2~3배 적은 것을 볼 수 있다. 많은 상투어boilerplate를 쓸 필요없고, 게다가 훨씬 더 재미있다.
이것은 우리가 개발자들에게 주는 강력한 도구이지만, 두 가지 면이 있다. 개발자들에게 많은 자유를 주지만 잘못된 사용을 피해야할 책임도 준다. 철학적으로 그게 자바와 스칼라의 가장 큰 차이점이라고 생각한다. 자바는 상당히 제한된 개념을 갖고 있어서 어떤 자바 프로그램이라도 다른 자바 프로그램과 좀 비슷해 보이고, 이는 프로그래머들을 교체하기swap 쉽도록 한다는 주장이 있다. 스칼라는 매우 표현적인 프로그래밍 언어이기 때문에 이러한 균일성은 없다.
스칼라 프로그램을 여러 가지 방법으로 개발할 수 있다. 자바로 시작한 프로그래머들에게 좋도록 자바처럼 짤 수도 있다. 이는 프로그래밍 그룹이 스칼라로 넘어오기 쉽도록 하고, 프로젝트의 리스크가 낮도록 한다. 그들은 중요하지 않은 부분부터 시작한 후 적당하다고 생각하는 속도로 범위를 넓힐 수 있다.
하지만 스칼라 프로그램을 완전히 함수적인 방법으로 짤 수도 있고 이런 프로그램들은 전형적인 자바 프로그램들과 전혀 달라 보일 수 있다. 종종 훨씬 더 간결하다. 이게 주는 이점은 고수준의 라이브러리나 스칼라에 내장된 DSL처럼 자신만의 관용구idioms를 개발할 수 있다는 것이다. 전통적으로, 똑같은 효과를 얻으려면 몇 가지 다른 언어나 설정 기법을 혼합해야 했다. 따라서 궁극적으로는 스칼라의 단일 언어 접근법이 더 간단한 해결책을 내놓게 할 수도 있다.
스칼라를 쓰기를 원하는 자바 개발자들에게는 학습 부담(learning curve)이 작겠지만 PHP나 파이선, 루비와 같이 동적 규율을 갖춘 동적 언어로 일하는 데 익숙한 프로그래머들이 배우기에는 어떨까?
확실히 자바나 닷넷 개발자들이 스칼라를 배우기 가장 쉽다. 다른 커뮤니티들에 관해서라면 걸림돌stumbling blocks은 언어 자체와는 별 관련이 없고, 패키징하는 법과 자바에 특정한 도구를을 구성set up하는 법이다. 이런 것들을 어떻게 구성하는지를 한 번 배우면, 언어 자체를 배우는 데는 어렵지 않을 것이다.
트위터가 스칼라를 쓰고 있는 것은 어떻게 생각하나? 이런 인지도 높은 사이트가 스칼라를 쓰는 게 스칼라 언어의 개발에 도움이 되나?
그것은 굉장한 소식이었다. 그들이 스칼라로 옮겨갔다는 것과 스칼라가 잘 쓰이고 있다는 게 기쁘다. 트위터는 외적인 성장을 잘 버텨왔고, 스칼라로 교체하기 전보다 더 견고해진 것 같다. 이는 스칼라에 좋은 증거testament라고 생각한다. 트위터처럼 인지도 높은 사이트가 새로운 언어를 채택하는 것은 그 언어에 매우 신랄한 테스트가 된다. 만약 그 언어에 커다란 문제들이 있다면 아마도 더 빨리 발견될 것이고 두드러지게 강조될 것이다.
스칼라를 채택하는 다른 잘 알려진 회사들도 많이 있다. 소니 픽쳐스 이미지웍스는 미들티어 소프트웨어 개발에 스칼라를 쓰고 유럽 최대의 에너지 회사인 EDF는 영업 부문에서 계약 모델링에 스칼라를 쓰고 있다. SAP와 지멘스 그들의 오픈 소스 기업 소셜 메시징 실험Enterprise Social Messaging Experiment(ESME) 도구에 스칼라를 쓰고 있다. 이는 많은 예 중에 단지 셋일 뿐이다.
트위터 개발자 중 한 명인 알렉스 페인은 스칼라가 그 새로운 웹 스타트업이 선택하는 언어가 될 수 있고, 매우 인기 있지만 스칼라 만큼 효율적이지 않은 파이선이나 루비 같은 언어보다 더 쓰일 수 있다고 했다. 이에 동의하나? 그리고 스칼라를 개발할 때 웹 2.0 스타트업들을 염두에 두었나?
스칼라가 이 영역에 적합다다고 본다. 이를 깨달은 것은 트위터뿐은 아니고 링크드인도 스칼라를 사용한다.
스칼라가 거기에 제공하는 것은 애자일한 언어를 쓰면서 견고한 고성능 플랫폼 - 자바 가상 머신(JVM) 위에 구축할 수 있는 능력이라고 생각한다. 자이선, J루비, 그루비, 클로저 등도 있지만 이것들은 모두 JVM에서 실행되는 동적 타입 언어이다.
결국 질문은 정적 타입 설정이 더 편하냐는 점에 도달하는데, 많은 에러를 일찍 잡을 수 있기 때문에 그럴 수도 있고, 리팩토링을 위한 안전망을 제공한다는 점에서, 또는 성능에 도움이 된다는 점에서 그럴 수도 있다. 혹은 메타 프로그래밍으로 화려한 것들을 하고 싶어서 완전한 동적 언어를 원할 수도 있다. 궁극적으로 그런 선택에 도달한다. 만약 정적 타입 언어를 원한다면 현재는 스칼라가 가장 좋은 선택이라고 생각한다.
스칼라의 특징 중에서 가장 좋아하는 것을 하나 꼽는다면?
가장 좋아하는 특징 하나를 고를 수 없을 것 같다. 오히려 스칼라의 특징들이 함께 작동하는 방식을 선택하겠다. 예를 들어, 고차 함수high-order functions가 어떻게 객체들과 추상 타입들과 함께 혼합되는지, 또는 스칼라에서는 함수가 상속될 수 있기 때문에 액터가 어떻게 가능해졌는지이다. 스칼라에서 가장 흥미로운 디자인 패턴들은 명확히 객체 지향과 함수형 언어 아이디어 사이의 상호 작용으로부터 유발된다.
앞으로 스칼라가 지향하는 것은?
단기적으로 다음 릴리즈인 스칼라 2.8을 위해 열심히 작업 중인데, 무엇보다도 고성능 배열 연산, 그리고 빠른 영속적인 데이터 구조를 가지고 컬렉션 라이브러리를 재정의하는 데 집중하고 있다. 올해 가을[북반구 기준으로]이면 나올 것이다.
그 후 장기적으로 동시성과 병행성 쪽에서 흥미로운 기회를 보고 있어서 멀티 코어 프로세서와 다른 병행 시스템에서 프로그래밍하는 데 새로운 방법을 찾고 있다. 스칼라는 동시성을 표현하는 고수준 방법을 제공하는, 유명한 액터 시스템을 갖고 있기 때문에 이미 여기에 유리한 점이 있다. 예를 들면 트위터의 메시지 큐에 사용된다. 재미있는 점은 스칼라에서의 액터는 언어 기능이 아니고 순수하게 스칼라 라이브러리로 구현됐다는 것이다. 따라서 이는 스칼라의 유연함에 대한 좋은 증거가 된다. 라이브러리에 적절한 기본 요소primitives와 관념abstractions을 포함시킴으로써 어플리케이션 프로그래머들에게 언어 기능으로 보이는 것들을 프로그래밍할 수 있다.
액터에 대한 작업이 데이터 병행성과 스트림 프로그래밍 등의 다른 동시성 관념concurrent abstractions에도 효과가 있기를 기대한다. 다른 종류의 병행성과 동시성은 다른 도구를 필요로 할 것이기 때문에, 미래에는 아마도 멀티 코어를 제대로 쓰기 위해 몇가지 동시성 관념이 필요할 것이라고 본다. 스칼라의 라이브러리 기반 접근이 여기에 적합하다고 보는데, 스칼라 클래스와 객체로 구현된 개념들을 섞고 매칭시켜서, 모든 것을 언어와 컴파일러에 넣는 것보다 빠르게 나아갈 수 있게 하기 때문이다. 다음 4,5년은 이 작업으로 바쁠 것 같다.
[삽질記] luabind를 사용하여 루아에서 C++ 코드 호출하기
* 환경 : ubuntu 10.10 x86_64(Live)
1. luabind 설치
문서에는 bjam을 사용하여 직접 빌드하는 방법이 나와 있지만 귀찮으니 시냅틱 패키지 관리자를 사용하여 설치하기로 하였다.
기본 저장소(main)에는 luabind가 없고 저장소 설정에서 universe 저장소를 체크해야 luabind를 찾을 수 있다
.
luabind로 찾으면 libluabind-dbg, libluabind-dev, libluabind-doc, libluabind-examples, libluabind0.9.0이라는 패키지들이 검색되는데, 모두 설치하였다(의존성이 있는 boost나 lua 관련 패키지들도 모두 설치).
설치가 끝나고 lua를 실행해보니, 'lua'가 없단다.--;
The program 'lua' can be found in the following packages:
* lua5.1
* lua40
Try: sudo apt-get install <selected package>
ubuntu@ubuntu:~$
luabind를 설치하면 알아서 깔릴 줄 알았더니 아니었다.
2. lua 설치
역시 시냅틱으로 lua를 설치했다(lua5.1과 lua5.1-doc 설치).
설치 후 lua를 실행시켜 보니, 이번에는 lua shell이 떴다.
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
>
3. Hello world 코드 작성 및 컴파일
이제 문서에 나온 Hello world 코드를 작성해야 하는데, 아까 깐 패키지 중에 libluabind-examples라는 이름이 왠지 수상하여 살펴보니, 예제 코드가 포함되어 있었다. 이로써 타이핑할 수고는 덜 수 있었다.
...
/usr/share/doc/libluabind-examples/examples/hello_world
/usr/share/doc/libluabind-examples/examples/hello_world/hello_world.cpp
/usr/share/doc/libluabind-examples/examples/hello_world/README
/usr/share/doc/libluabind-examples/examples/hello_world/Makefile
...
ubuntu@ubuntu:~$
퍼미션 문제가 있으니 Hello world 코드를 홈 디렉터리로 복사하고 make를 실행하였다.
g++ -shared hello_world.cpp -o hello_world.so -I/sw/include -L/sw/lib \
-I/usr/include/lua5.1 -I/usr/include/boost \
-llua5.1 -lluabind
/usr/bin/ld: /tmp/ccBd0u3H.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
/tmp/ccBd0u3H.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [helloworld_test] Error 1
ubuntu@ubuntu:~/hello_world$
예상대로(--;) 실패한다. 친절한(?) 에러 메시지를 따라서 Makefile에 -fPIC를 추가하고 다시 make를 실행했다.
# if using fink on darwin
# you need these additional flags
CPPFLAGS = -I/sw/include -L/sw/lib -fPIC
helloworld_test: hello_world.cpp
$(CXX) -shared hello_world.cpp -o hello_world.so $(CPPFLAGS) \
-I/usr/include/lua5.1 -I/usr/include/boost \
-llua5.1 -lluabind
clean:
rm -f helloworld *.o *~
이번에는 성공했다. hello_world.so라는 파일(shared library)이 생겼다.
4. lua shell에서 Hello world 불러오기
lua shell을 실행한 후, 문서에 나온대로 따라해 봤다
(문서에는 'hello_world.dll'가 나와 있지만 리눅스이므로 'hello_world.so'를 사용했다.)
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> loadlib('hello_world.so', 'init')()
stdin:1: attempt to call global 'loadlib' (a nil value)
stack traceback:
stdin:1: in main chunk
[C]: ?
>
역시나 바로 되는 일은 없다. --;
여기가 가장 고생한 부분이다. 여기 저기 검색하며 뒤져보다가 최근 버전의 lua에서는 loadlib() 대신 package.loadlib()를 쓰는 것으로 바뀌었다는 내용을 보았다(링크는 잊어버렸다).
어쨌든 package.loadlib()로 바꿔서 시도해봤다.
stdin:1: attempt to call a nil value
stack traceback:
stdin:1: in main chunk
[C]: ?
>
또 안된다. --; 대신 에러 메시지는 달라졌다. 여기 저기 뒤져봤지만, 해결책은 찾지 못했다.
거의 포기하려다가 혹시나 하는 마음으로 so 파일의 경로에 './'를 추가해 봤다.
> greet()
hello world!
>
드디어 성공이다! 이거 하나 띄우려고 며칠을 고생했던가... 젠장, 문서에 몇 글자만 고쳐져 있었으면 이렇게 고생을 안 했을텐데.. 루아에 대해 전혀 모른 상태여서 더 어려운 점도 있었다.
어쨌든 이번 일로 얻은 교훈은 있다.
* 문서를 참조할 때는 그대로 믿지 말라.
* 오래 방치된 문서는 누군가를 삽질의 세계로 인도할 수 있다.
(추가)
이 글을 쓰면서 examples/hello_world/README 파일을 열어 보았더니, 거기에는 다음과 같은 내용이 있는 게 아닌가! 이 파일을 열어 보았다면 한 번의 삽질은 줄일 수 있었을 텐데, 가까운 곳을 찾지는 않고 먼 곳을 뒤지고 있었던 것이다.
this example will build an extension module as a shared library, use
loadlib() from within the lua interpreter to load the library, it will
then export a function named greet() which you can call.
> loadlib('./hello_world.so', 'init')()
> greet()
Hello world!
>
* 패키지나 소스를 사용하기 전에 첨부된 README 파일은 꼭 읽어보자.
리눅스에서 mbc 라디오 온에어 듣기
예전에 kbs 온에어를 리눅스에서 듣는 방법을 찾아본 적이 있어 imbc 사이트에도 한 번 도전해 보기로 했다. Active-X를 사용하더라도 최종적으로 mms URL을 보내주는 과정은 있을 것이라는 믿음으로 시작했다.
이번에는 ethereal(http://www.ethereal.com)을 사용하기로 했다. 윈도우 XP에서 ethereal을 실행하여 익스플로러로 imbc 온에어를 최종적으로 듣기 까지의 패킷을 캡쳐했다. 아래처럼 여러 패킷이 보이는데 그 중 "playercue.imbc.com"가 눈에 띄었다. 온에어를 실행할 때 뜨는 팝업창의 주소이기 때문이다.
playercue.imbc.com으로 오고 가는 패킷을 하나씩 살펴 봤지만 raw 메시지를 보려니 쉽지 않았다. 패킷의 내용을 문자열로 변환해서 함께 보여주기는 하지만 역시 난해하다. 그러다가 "Follow TCP Stream"이라는 메뉴를 발견했다.
이 기능은 하나의 TCP 커넥션에서 오고 가는 패킷을 모아 차례대로 보여주는 기능인데, 다음과 같이 HTTP 패킷을 보기 좋게 정리해 준다.
가장 마지막 부분을 보면 ASX 태그 안에 mms URL이 포함되어 있는 것을 볼 수 있다. 온에어 주소 뒤에 긴 문자열이 있는데 인증 문자열 보인다. 이 주소를 긁어다가 곰플레어로 재생해 보니 잘 나왔다. 뭔가 되가는 것 같다. 이제 문제는 어떻게 인증 문자열을 포함한 주소를 얻어내느냐인데 역시 위에 답이 있었다.
ASX 메시지를 받기 직전을 보면 GET /Player/ .. 이렇게 요청한 URL 주소가 나와 있다. imbc 사이트에 로그인한 후 이 주소로 접속해보니 ASX 파일이 나오고 그 파일을 열어보니 인증 문자열이 추가된 mms URL이 들어 있었다.
몇 번을 테스트한 결과 불필요한 부분은 빼고 http://playercue.imbc.com/player/Player.asp?Subclass=LR&MediaUrl=mms://liveradio.imbc.com/OnAirMFM로 접속하면 된다는 것을 알 수 있었다(OnAirMFM은 FM4U를 의미. 표준FM은 OnAirMFM 대신 OnAirSFM을 쓰면 된다.)
이제 리눅스 / 파이어폭스 환경에서도 되는 지만 확인해 보는 일만 남았다. 같은 방법으로 접속해 보니 토템 플레이어가 뜨면서 imbc 온에어 재생 시 나오는 광고 동영상이 몇 개 나오지만 온에어는 나오지 않았다. 뭔가 이상하다 싶어 파이어폭스 환경 설정에서 토템이 열리지 않도록 하고 다시 해보니, ASX 파일이 다운로드 되지만 윈도우/익스플로러와는 달리 mms URL 부분에 인증 문자열(REF 태그의 HREF attribute에 있는 '?'로 시작하는 문자열)만 붙어 있었다. 토템을 열어 주소 창에 "mms://liveradio.imbc.com/OnAirMFM"을 치고 끝에 인증 문자열을 붙인 후 재생을 하니 잘 나왔다. 왜 리눅스/파이어폭스에서는 full URL이 나오지 않는 지는 알 수 없지만 리눅스에서도 imbc 라디오 온에어를 들을 수 있게 된 것이다(다른 버전으로는 실행을 안해봐서 파폭 버전에 따른 문제인지는 모르겠다.)
방법만 정리하면,
2. 파이어폭스로 http://playercue.imbc.com/player/Player.asp?Subclass=LR&MediaUrl=mms://liveradio.imbc.com/OnAirMFM에 접속해 ASX 파일을 다운 받는다(표준FM은 OnAirMFM 대신 OnAirSFM을 사용)
3. ASX 파일을 열어 인증 문자열을 복사한다.
4. 토템 등의 동영상 플레이어를 실행하고 주소 창에 mms://liveradio.imbc.com/OnAirMFM
를 입력하고 뒤에 3에서 얻은 인증 문자열을 붙여 넣고('?' 포함) 재생한다.
5. 즐겁게 듣는다.
※ 인증 후 재생을 두 번 이상 시도하면 막히는 kbs와는 달리 mbc의 인증 정보는 시간이 지나도 만료되지 않는 것 같다.
[리눅스 라디오 프로그램 제작기] 2. kbs 온에어 재생
프로그램은 크게 두 가지 부분으로 나뉘어 진다. 먼저 kbs 사이트에 로그인한 후 mms url을 얻어오는 부분, 그리고 mms url을 재생하는 부분이다. 이 중에서 mms 재생하는 부분은 GStreamer 매뉴얼의 playbin 항목을 참고했다. 볼륨 조절이나 정지/재생 기능은 일단 고려하지 않고 단순히 재생하는 데만 초점을 맞추었기 때문에 예제 코드를 거의 그대로 갖다 썼다.
kbs 사이트에 로그인하는 부분은 조금 삽질이 필요했다. 파이어폭스 확장 기능인 httpfox를 사용하여 로그인부터 온에어 url이 전송되는 부분까지 거쳐 가는 페이지들을 추적했다. 서버 단에서 일어나는 일들을 정확히 알 수 없었기 때문에 httpfox에서 보이는 http request/response를 보고 추측해야 했다. 이렇게 알아낸 것들을 바탕으로 libsoup 라이브러리를 사용하여 http request를 보내고 response를 받으며 mms url이 나올 때까지 계속해 갔다. 그리고 이 과정에서 쿠키에 저장되는 정보가 있는데 request를 보낼 때 설정해 주어야 했다. 이런식으로 로그인부터 mms url을 얻어오는 데 성공하기 까지 며칠은 걸린 것 같다. libsoup 튜토리얼이라도 있었으면 좀 쉽게 했을텐데...
어쨌듯 온에어를 재생하는 데 성공했으니 이제 다음으로 GUI를 붙여 봐야 겠다.
소스 설명
get_url.h, get_url.c : kbs 사이트에 로그인하고 mms url을 얻어오는 코드(libsoup 사용)
player.h, player.c : mms url을 재생하는 코드(GStreamer 사용)
main.c : 말 그대로 메인
이번에 사용한 GStreamer 코드는 얼마되지 않는다. 위에서도 말했듯이 playbin 코드를 많이 참고하였고, 필요한 부분만 뽑았기 때문에 간단하다.
libsoup 사용 부분은 조금 길긴 하지만 HTML 폼 파라미터 처리가 필요하고 http request를 여러 번 주고 받아야 되어서 길어졌을 뿐, 실제로 사용한 libsoup 함수는 몇 가지 안된다.
soup_message_set_request(); // 폼 데이터와 함께 POST request를 보낼 때 사용
soup_session_send_message(); // http request를 보냄
soup_message_headers_append(); // http 헤더 셋팅(kbs 사이트에 referer를 체크하는 부분이 있어 사용했다.)
soup_cookies_to_request(); // request에 쿠키를 포함할 때 사용
컴파일 및 실행 방법
※ 이전 글에서 설명한 개발 라이브러리들이 설치되어 있어야 컴파일이 된다.
./Makefile
./get_url.c
./get_url.h
./main.c
./onair
./player.c
./player.h
young@y0un5:~/Study/onair$ ls
Makefile get_url.c get_url.h main.c onair onair.tar.gz player.c player.h
young@y0un5:~/Study/onair$ make
gcc -o onair main.c get_url.c player.c `pkg-config --cflags --libs libsoup-2.4 gstreamer-0.10`
young@y0un5:~/Study/onair$
young@y0un5:~/Study/onair$ ./onair [채널 - 1AM, 2FM 등] [kbs 사이트 ID] [패스워드]
[DEBUG] Dest URL : L_2FM
[DEBUG] got onair url : mms://211.233.92.42/L_2FM?[ID]
[DEBUG] now play mms://211.233.92.42/L_2FM?[ID]
[리눅스 라디오 프로그램 제작기] 1. 개요 & 개발 환경 구축
개발 목적
이 프로젝트의 목적은 간단하다. 리눅스에서 간편하게 쓸 수 있는 GUI 라디오 프로그램을 만드는 것이다. kbs의 콩, mbc의 미니, sbs의 고릴라 등의 리눅스 버전이라 생각하면 되겠다. mbc, sbs 등 스트리밍 url이 공개되어 있고 로그인하지 않아도 되는 것들은 바로 그 url을 재생하고 kbs처럼 로그인이 필요한 것은 사이트에 직접 접속하여 스트리밍 url을 얻어와 재생하는 방식으로 구현할 것이다. (사실 이 프로그램을 만들기로 결심한 것은 kbs 때문이다. 공개된 url은 없고, 사이트에서도 온에어 링크가 잘 작동이 안되었기 때문이다. 그런데 어제 다시 kbs 사이트에서 온에어를 실행해보니 팝업 차단을 하면 잘된다..ㅡㅡ; 뭐, 그래도 일단 시작한 것이니 계속 진행 해 봐야지...)
기능
기능은 별 거 없다. 일단 생각하고 있는 것은 이 정도...
1. kbs, mbc, sbs 라디오 채널 재생
2. 기타 채널 추가 기능
3. 녹음 기능
4. 예약 기능
5. 프로그램 정보 읽어 오기
개발 환경
이 참에 GNOME 어플리케이션 공부도 할 겸 개발 환경은 GNOME을 선택했다. 그리고 스트리밍 재생을 위한 프레임워크로는 GStreamer를, HTTP 클라이언트로는 libsoup를 사용하기로 했다. GUI는 일단 Gtk+로 만들고 나중에 GNOME 어플리케이션으로 변경해 보려 한다.
Tool : vim / gcc / Anjuta
GUI : Gtk+ (추후 GNOME 어플리케이션으로 변경)
멀티미디어 프레임워크 : GStreamer
HTTP 클라이언트 : libsoup
개발 환경 구축
■ Gtk+ 개발 관련 패키지 설치
먼저 Gtk+로 개발할 때 필요한 파일들이 포함된 libgtk2.0-dev 패키지(및 의존성 걸리는 패키지들)를 설치한다. 설치 후 다음 명령을 실행했을 때 아래와 같이 인클루드 경로와 링크 플래그가 나와야 한다. 이 정보는 gcc로 gtk+ 프로그램을 컴파일할 때 사용된다.
-I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lpangoft2-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lgio-2.0 -lcairo -lpango-1.0 -lfreetype -lz -lfontconfig -lgobject-2.0 -lgmodule-2.0 -lglib-2.0
young@y0un5:~$
Gtk+ 컴파일도 해보고 예제 참고도 할 겸, gtk2.0-examples 패키지도 설치한다. 이 패키지를 설치하면
/usr/share/doc/gtk2.0-examples/examples/에 예제 소스가 Makefile과 함께 설치된다.
/usr/share/doc/gtk2.0-examples/examples/helloworld$에 helloworld.c 소스 파일이 있다. make를 실행하면 문제 없이 컴파일 되어야 한다(디렉토리 쓰기 권한이 root로 되어 있다는 것에 주의). Makefile을 열어 보면 pkg-config로 얻은 정보가 컴파일 시 사용되는 것을 볼 수 있다.
CC = gcc
CFLAGS = -Wall \
-DG_DISABLE_DEPRECATED \
-DGDK_DISABLE_DEPRECATED \
-DGDK_PIXBUF_DISABLE_DEPRECATED \
-DGTK_DISABLE_DEPRECATED
helloworld: helloworld.c
$(CC) helloworld.c -o helloworld $(CFLAGS) `pkg-config gtk+-2.0 --cflags --libs`
clean:
rm -f *.o helloworld
young@y0un5:/usr/share/doc/gtk2.0-examples/examples/helloworld$
vim 플러그인 gtk-vim-syntax도 설치하면 vim으로 작업하기 편하다. 당분간은 에디터로 vim을 쓸 것이기 때문에 이 플러그인도 설치하는 게 좋다. 설치 방법은 간단하다. 파일을 다운 받아 "~/.vim/after/syntax/"에 압축을 푼 후 c.vim.example 파일을 c.vim으로 변경하면 된다.
■ GStreamer 개발 패키지 설치
스트리밍 재생 기능을 구현하기 위해 GStreamer 개발 패키지를 설치한다. libgstreamer0.10-dev 패키지를 설치하고 이번에도 pkg-config를 실행하여 그 결과를 확인해 본다.
-pthread -I/usr/include/gstreamer-0.10 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/libxml2 -pthread -lgstreamer-0.10 -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lrt -lxml2 -lglib-2.0
young@y0un5:~$
GStreamer 튜토리얼 사이트에 나온 helloworld 예제가 제대로 컴파일 되고 실행되는 지 확인해 본다.
■ libsoup 개발 패키지 설치
사실 이 라이브러리는 온에어 방송을 듣는 데 필요 없지만 kbs는 사이트 로그인 후에만 스트리밍 재생이 되도록 되어 있기 때문에 HTTP 클라이언트 기능이 있어야 한다. HTTP 클라이언트 라이브러리로 libsoup를 택한 것은 별 다른 이유는 없고 GNOME Development Reference 사이트에 나와 있어서 그냥 쓰기로 했다. libsoup2.4-dev 패키지를 설치하고 역시 pkg-config를 실행하여 제대로 나오는 지 확인해 본다.
이제 IDE를 제외한 개발 환경은 모두 구축되었다. Anjuta IDE는 나중에 GUI를 만들 때 설치하기로 하고, 이제 Gtk+, GStreamer, libsoup를 공부해야 할 시간이다.
※ 참고 사이트
libsoup Reference Manual : http://library.gnome.org/devel/libsoup/stable/
GStreamer Application Development Manual : http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/index.html
리눅스/파이어폭스로 kbs 온에어 듣기
리눅스에서도 라디오를 들을 수는 있다. 라디오 URL이 대부분 mms로 되어 있기 때문에 그 주소만 안다면 mms 재생 가능한 플레이어를 사용해서 들을 수 있다. mbc와 sbs, 그리고 몇몇 방송들은 이 방법을 사용하면 들을 수 있다. (http://ubuntu.or.kr/viewtopic.php?p=11644)
하지만 kbs는 그렇지가 않다. 알려진 mms 주소도 없어 kbs 사이트 온에어를 통해 들으려고 해봤지만 역시 파이어폭스는 제대로 지원이 안 됐다. 작년에 리눅스에서 kbs 온에어를 들으려고 삽질한 끝에 몇 가지 사실을 알 수 있었다.
2. mms 주소가 일정하지 않다. IP 주소가 거의 비슷하긴 하지만 항상 동일하지는 않다.
결국 일단 kbs 사이트에 로그인을 하되 사이트의 온에어 링크로는 접근이 안되니, 다른 경로를 찾아야 한다는 것을 알 수 있었다.
2009. 1. 4. 추가 : 희한하게 팝업 차단을 하고 링크를 누르면 온에어가 작동이 된다ㅡㅡ;(FF 3.0.5 버전). 그 동안 삽질한 게 좀 허무하기도 하지만 그 덕에 공부 좀 했으니 그 시간이 아깝지는 않다.
리눅스 비프음 끄기
X윈도우에서 # xset b off
매번 실행하기 귀찮다면 다음을 ~/.bashrc 파일에 추가해 준다.
-------------------------------------------
if [ "$TERM" = "xterm" ]; then
xset b off
elif [ "$TERM" = "linux" ]; then
setterm -blength 0
fi
--------------------------------------------
Fedora Core 6 한글 환경 설정하기
1. 한글 폰트 설치
Fedora Core 6를 텍스트 모드에서 설치한 후 재부팅하면 다음과 같이 글자가 제대로 나오지 않는다(영문 그래픽 설치 후 한글 환경으로 바꿔도 같은 현상이 발생한다.) 이는 한글 폰트 패키지(fonts-korean)가 설치되지 않았기 때문이다. 따라서 yum을 사용하여 설치해줘야 한다.
1-1) 페도라의 yum은 http://mirrors.fedoraproject.org에서 미러를 찾아 사용하도록 설정되어 있지만 한국 미러가 존재하지 않기 때문에 그대로 yum을 사용하면 매우 느리다(http://fedora.redhat.com/Download/mirrors.html에는 한국 미러가 지정되어 있던데 왜 저기는 없는지 모르겠다). 그러므로 수동으로 한국 미러를 사용하도록 고쳐준다(여기서는 카이스트 미러를 사용한다).
/etc/yum.repos.d/fedora-core.repo,
/etc/yum.repos.d/fedora-updates.repo,
/etc/yum.repos.d/fedora-extras.repo 이 세 파일을 연 후, mirrorlist 줄을 주석처리하고 baseurl을 주석해제한 후, url을 각각 다음처럼 고쳐준다.
baseurl=ftp://ftp.kaist.ac.kr/pub/fedora/linux/core/$releasever/$basearch/os/
baseurl=ftp://ftp.kaist.ac.kr/pub/fedora/linux/core/updates/$releasever/$basearch/
baseurl=ftp://ftp.kaist.ac.kr/pub/fedora/linux/extras/$releasever/$basearch/
1-2) yum을 사용하여 fonts-korean을 설치한다.
[root@FC6 ~]# yum install fonts-korean
이제 X윈도우를 재시작하면 한글이 잘 나오는 것을 볼 수 있을 것이다.
2. 한글 입력기 설치
이제 한글을 볼 수는 있게 되었는데 아직 한글 입력은 불가능하다. 한글을 입력하려면 한글 입력기 패키지들을 설치해줘야 한다.
앞서와 마찬가지로 yum을 사용하여 필요한 패키지(scim-libs, scim,scim-hangul)를 설치한다.
[root@FC6 ~]# yum install scim-hangul
(scim-libs, scim이 함께 설치된다.)
다시 X윈도우를 재시작하면 패널에 scim이 떠 있는 것을 확인할 수 있으며, Shift+Space 또는 Ctrl+Space를 사용하여 한/영 전환을 할 수 있다.
※ 한/영키, 한자키 사용하기
----------------------------------------------------------------------------
1) # xev를 실행한 후, 한/영키, 한자키를 눌러 키코드를 알아낸다.
2) /etc/X11/Xmodmap 파일에 다음과 같이 추가한다(키코드가 209, 210일 경우)
...
keycode 209 = Hangul_Hanja
keycode 210 = Hangul
...
3) scim 설정에서 변환키에 한/영키, 한자키를 추가한다.
------------------------------------------------------------------------------
※ KDE에서 한글을 사용하려면 kde-i18n-Korean 패키지가 필요하다. 앞서와 같이 yum을 사용해 설치하면 된다.
# service mysqld start
(mysql 데몬은 mysql 계정으로 실행됨)
2. mysql이 작동 중인지 테스트하기
1) 실제로 접속해서 확인하기
$ mysql -u root mysql ( root로 mysql 데이터베이스에 접속한다. )
mysql> \s (서버 정보 보기)
mysql > \q 또는 quit (나가기)
2) 또는 mysqladmin으로 확인하기
$ mysqladmin -u root version (실행 중인 mysql 서버 정보를 보여준다.)
3. root 패스워드 변경
1) $ mysqladmin -u root password [패스워드] 를 사용해서 root 패스워드를 변경할 수 있다. 그러나 shell history에 패스워드가 텍스트로 남게 되므로 보안 상 좋지 않다.
2) mysql에 접속해서 변경하기
$ mysql -u root
mysql> set password=password('패스워드');
패스워드를 설정한 후에는 $ mysql -u root -p 실행한 뒤, 패스워드를 쳐야 접속할 수 있다.
※ mysql의 root는 시스템 계정 root와는 아무 관계가 없다. 계정을 가진 어떤 사용자도 mysql에 접속할 수 있다.
4. root를 localhost에서만 접속 가능하도록 설정하기
보안상 root 사용자는 localhost에서만 접속 가능하도록 설정하는 게 좋다.
$ mysql -u root -p (mysql에 root로 접속)
mysql> select user, host, password from mysql.user;
(현재 등록되어 있는 사용자들의 id, 접속 가능한 호스트, 패스워드를 확인)
+------+-----------+------------------+
| user | host | password |
+------+-----------+------------------+
| root | localhost | 574a3a0a1e20ce6e |
| root | young | |
| | young | |
| | localhost | |
+------+-----------+------------------+
4 rows in set (0.01 sec)
mysql> delete from mysql.user where host != 'localhost';
(localhost가 아닌 곳에서는 접속할 수 없도록 함)
mysql> select user, host, password from mysql.user;
+------+-----------+------------------+
| user | host | password |
+------+-----------+------------------+
| root | localhost | 574a3a0a1e20ce6e |
| | localhost | |
+------+-----------+------------------+
2 rows in set (0.01 sec)
5. 사용자 추가하기
mysql> grant all on *.* to user@localhost identified by 'secretpassword';
※ Beginning Linux Programming 3rd 참고...
[Qt] 어플리케이션 다국어 지원
1. 어플리케이션의 .pro 파일에 번역 파일(.ts)를 지정하는 부분 추가
예)
TRANSLATIONS = spreadsheet_de.ts \
spreadsheet_fr.ts
2. lupdate 툴 사용하여 .ts 파일 생성
# lupdate -verbose spreadsheet.pro
3. Qt Linguist로 .ts 파일을 열어 각 언어에 맞게 번역
4. File | Release 메뉴 사용하여 .ts 파일을 .qm 파일로 변환
(모든 .ts 파일을 .qm 파일로 변환하고자 한다면 : # lrelease -verbose spreadsheet.pro)
※ .ts 파일(Translation Source) : XML 포맷, 번역시 사용.
.qm 파일 (Qt message) : 어플리케이션에서 사용(QTranslator).
<참고 >
C++ GUI Programming with Qt3
http://doc.trolltech.com/3.3/linguist-manual.html