2007년 8월 10일 금요일

파이썬으로 하는 웹 클라이언트 프로그래밍

[한빛미디어] 2002-12-16 11:51 / 조회수 1,369

저자: 데이브 워너(Dave Warner), 역 전순재

웹 클라이언트 프로그래밍은 웹에서 정보를 찾게 도와주는 강력한 테크닉이다. 웹 클라이언트는 (웹 주소 앞에 붙은 http) 하이퍼 텍스트 전송 프로토콜[1]을 사용하여 웹 서버로부터 데이터를 열람하는 프로그램 모두를 말한다. 웹 브라우저는 클라이언트이다. 웹 크롤러(crawler) 역시 클라이언트이다. 이 프로그램은 웹을 자동적으로 돌아다니면서 정보를 수집한다. 웹 클라이언트를 사용하면 웹에서 다른 사람들이 제공하는 서비스들을 이용할 수 있으며 웹 사이트에 역동적인 특징들을 추가할 수도 있다.

개발자들이 사용하는 툴박스에는 자연스럽게 웹 클라이언트 프로그래밍이 들어있다. 펄(Perl) 열성팬들은 이미 수년간 웹 클라이언트 프로그래밍을 이용해 왔다. 이런 웹 클라이언트 프로그래밍은 파이썬으로 처리하면 편리성과 유연성이 더욱 높은 수준에 이른다. 여기에 필요한 모든 기능들은 모듈 3개로 해결할 수 있다. HTTPLIB, URLLIB, 그리고 더 새로워진 XMLRPCLIB가 바로 그것들이다. 진정한 파이썬 스타일로, 각 모듈은 기존의 모듈 위에 구축되어 애플리케이션에 견고하면서도 잘 디자인된 기반을 제공한다. XMLRPCLIB는 다음에 논하기로 하고 본 기사에서는 첫 번째 모듈 두 개에 대해 다루겠다.

우리가 볼 예제에서는 미어캣(Meerkat)을 사용하겠다. 이럴 경우 여러분이 필자와 같은 생각을 가지고 있다면 시간을 들여 오픈 소스 공동체의 동향과 개발 상황들을 추적해서 경쟁력을 확보할 것이다. 미어캣(Meerkat)은 이 작업을 훨씬 더 쉽게 만들어주는 도구이다. 미어켓은 오픈 와이어 서비스(open wire service)로서 오픈 소스 컴퓨팅과 관련된 방대한 양의 정보를 수집하고 정리한다. 미어캣의 브라우저 인터페이스는 유연하고 맞춤가능하지만, 웹 클라이언트 프로그래밍을 사용하면 우리는 이 정보를 훓어보고, 추출하는 것은 물론이고 나중에 사용하기 위해 오프 라인에 저장할 수도 있다. 우리는 먼저 HTTPLIB를 상호대화적으로 사용하여 미어켓에 접근할 것이다. 그리고 나서 URLLIB를 통해 미어켓의 개방 API(Meerkat's Open API)에 접근해 들어가 맞춤가능한 정보 수집도구를 만들어 볼 것이다.

HTTPLIB

HTTPLIB는 소켓(socket) 모듈을 살짝 감싼 포장자(wrapper)이다. 앞에서 언급한 3개의 라이브러리 중에서 웹 사이트에 접근할 때 가장 제어가 쉬운 모듈이 HTTPLIB이다. 그렇지만 과업을 달성하기 위해서는 추가 작업을 더 해야만 제대로 제어할 수 있다. http 통신규약(protocol)은 "정보를 저장하지 않기(stateless)" 때문이다. 따라서 이전의 요구는 전혀 기억하지 않는다. 각 요구에 대해 여러분은 HTTPLIB 객체를 새롭게 구성하여 웹 사이트에 접속해야 한다. 요구들은 웹 서버와 대화를 형성하고 웹 브라우저를 흉내낸다. 라엘 돈페스트(Rael Dornfest)의 개방 API를 사용해서 미어켓에 접속해 보자. 그리고 어떤 결과를 얻는지 살펴 보자. 대화는 일련의 서술문들을 구축함으로써 시작된다. 먼저 원하는 작업이 무엇인지 서술한다. 그리고 나서 웹 서버에게 여러분을 식별시킨다.
>>> import httplib
>>> host = 'www.oreillynet.com'
>>> h = httplib.HTTP(host)
>>> h.putrequest('GET', '/meerkat/?_fl=minimal')
>>> h.putheader('Host', host)
>>> h.putheader('User-agent', 'python-httplib')
>>> h.endheaders()
>>>

GET 요청은 어느 페이지를 받기 원하는지 서버에게 전달한다. 호스트 헤더(Host header)는 질의하고자 하는 도메인 이름을 서버에게 전달한다. 현대적인 서버들은 HTTP 1.1을 사용하여 여러 도메인을 같은 주소에서 사용할 수 있다. 만약 서버에게 어떤 도메인 이름을 원하는지 알려주지 않는다면, 여러분은 '302' 출력전환(redirection) 응답을 반환 코드로 얻게 될 것이다. 사용자-에이전트 헤더(User-agent header)는 서버에게 여러분이 어떤 종류의 클라이언트인지 알려 준다. 그래야만 서버는 여러분에게 보낼 수 있는 것과 없는 것이 무엇인지를 이해할 수 있기 때문이다. 이것이 웹 서버가 요구를 처리하기 위해 필요한 정보이다. 다음으로 여러분은 응답을 요구한다.
>>> returncode, returnmsg, headers = h.getreply()
>>> if returncode == 200: #OK
... f = h.getfile()
... print f.read()
...

이렇게 하면 현재의 미어켓 페이지를 간략한 형태(minimal flavor)로 출력할 것이다. 응답 머리부와 응답 내용은 개별적으로 반환되며, 이렇게 하면 반환된 데이터의 문제를 해결하거나 해석하는데 모두 도움이 된다. 만약 응답 머리부를 보고 싶다면, print headers를 사용하면 된다.

HTTPLIB 모듈은 소켓 프로그래밍의 기계적인 면을 구별해준다. 게다가 HTTPLIB 모듈은 버퍼링을 위해 파일 객체를 사용하기 때문에 친숙하게 데이터 조작에 접근할 수 있지만 더욱 강력한 웹 클라이언트 애플리케이션을 위한 빌딩 블록이나 문제가 생긴 웹사이트와 상호 대화를 나누기 위한 빌딩 블록으로 더 잘 맞는다. HTTPLIB 모듈이 가지는 유용한 디버그 능력은 두 영역 모두에 도움을 준다. 객체 초기화 후에 어느 곳에서나 h.set_debuglevel(1) 메소드를 호출하면 HTTPLIB에 접근할 수 있다. (예제에서는 다음의 h = httplib.HTTP(host) 라인이다). 디버그 수준이 1에 설정되어 있으면 HTTPLIB 모듈은 getreply()을 호출한 결과들과 요청들을 화면에 응답할 것이다.

파이썬의 상호대화적인 특성 덕분에 즐겁게 HTTPLIB를 사용하여 웹 사이트를 분석할 수 있다. 이 모듈을 익히면 웹 사이트의 문제점들을 진단하기 위한 강력하고 유연한 도구를 가지게 되는 것이다. 또 시간을 가지고 HTTPLIB에 대한 소스를 살펴보라. 200줄도 안되는 코드임에도 불구하고, HTTPLIB를 사용하면 빠르고 쉽게 파이썬으로 소켓 프로그래밍을 시작할 수 있다.

URLLIB

URLLIB는 HTTPLIB에서 발견되는 기능에 대해 세련된 인터페이스를 제공한다. URLLIB 모듈은 웹 사이트를 분석하는 것보다는 데이터 그 자체를 찾아 내는데 가장 유용하게 사용된다. 다음 코드는 URLLIB를 사용해서 위와 똑같은 상호작용을 한다. (주의: 마지막 줄을 화면 출력을 위해 두 줄로 쪼개었지만, 여러분의 스크립트에서는 나누지 말 것!)
>>> import urllib
>>> u = urllib.urlopen
('http://www.oreillynet.com/meerkat/?_fl=minimal')

이것이 다이다! 한 줄로 미어켓(Meerkat)에 접근해서 데이터를 얻었으며, 그 데이터를 임시 저장소에 보관했다. 해더 정보에 접근하려면
>>> print u.headers

그리고 전체 파일을 보려면
>>>print u.read()

그러나 이것이 전부는 아니다. URLLIB는 HTTP뿐만 아니라 FTP, Gopher, 심지어는 같은 방식으로 지역 파일에도 접근할 수 있다. 이 모듈이 제공하는 많은 유틸리티 기능에는 url 해석하기, 문자열을 url-안전 형태로 코드전환(encode)하기, 그리고 한참 긴 데이터 전송 중에 진행 표시를 제공하기가 있다.

미어켓을 사용하는 예제 하나

한 그룹의 고객(client)들이 있는데 그들이 최신 리눅스 소식을 이메일로 꾸준히 받아보기를 바라고 있다고 상상해보자. 우리는 짧은 스크립트를 작성할 수 있다. URLLIB를 사용하여 이 정보를 Meerkat으로부터 얻는다. 링크의 목록을 구축한다. 그리고 그 링크들을 나중에 전송하기 위해 파일에 저장한다. 미어켓(Meerkat)의 저자인 라엘 돈페스트(Rael Dornfest)는 미어켓 API를 통해 우리 대신 대부분의 작업을 이미 완성해 놓았다. 남아있는 것은 요구를 구성하고, 링크를 해석하며, 나중에 전송하기 위해 그 결과를 저장하는 것 뿐이다.

단지 이것 때문에 사람들이 미어캣으로 전향하는 것일까? 이러한 "정보받기(passive)" 서비스를 제공하면 사람들은 그 정보를 한가할 때 볼 수 있다. 그리고 그 정보를 골라서 친숙한 형식(예를 들어 이메일)으로 저장할 수 있다. 월요일 아침에 메일함에서 뉴스들이 도착하기를 기다리기만 하면, 한 주간 "말려 올라간" 정보들을 하나도 놓치지 않을 것이다.

미어캣의 간략한 형식(minimal flavor)은 기사가 15개로 제한되므로 데이터를 놓칠 가능성을 줄이기 위해 우리는 스크립트를 (즉, Unix의 cron 작업 또는 NT의 AT 명령어를 사용하여) 매 시간 실행시킬 것이다. 여기에 우리가 사용할 url이 있다 (주의: 우리는 이 줄을 두 개의 줄로 나누어 화면에 표시했다. 이 URL을 사용한 결과는 여기에서 볼 수 있다).
http://www.oreillynet.com/meerkat/?p=5
&t=1HOUR&_fl=minimal&_de=0&_ca=0&_ch=0&_da=0

이 코드는 지난 한 시간 동안에 있었던 모든 리눅스 이야기들(profile=5)을 끌어 와서, 데이터를 간략한 형식(minimal flavor)으로 보여준다. 설명도 없고, 범주정보도 없으며, 채널 정보, 데이터 정보도 없다. 우리는 또한 정규 표현식 모듈의 도움을 받아 링크 정보를 추출하고 출력결과를 추가 모드로 열려진 파일 객체로 방향전환할 것이다.

결론

우리는 겨우 이 모듈들의 표면만을 건드려 보았다. 웹 클라이언트 작업에 사용할 수 있는 것 말고도 파이썬에는 다른 많은 네트워크 프로그래밍 모듈을 사용할 수 있다. 웹 클라이언트 프로그래밍은 특히 방대한 양의 계산표형 테이터를 다룰 때 유용하게 사용할 수 있다. 최근의 한 전자 데이터 교환(EDI) 프로젝트에서 우리는 웹 클라이언트 프로그래밍을 사용하여 거추장스러운 독점 소프트웨어 패키지를 우회하였다. 갱신된 가격 정보를 웹으로부터 직접 얻어서 데이터베이스에 집어 넣었다. 그렇게 함으로써 우리는 많은 시간을 절약하고 좌절감을 극복할 수 있었다.

웹 클라이언트 프로그래밍은 웹 사이트의 구조와 견고성을 테스트하는 데에도 유용하게 사용될 수 있다. 일반적으로는 죽은 링크들을 점검하는 방법으로 사용된다. 표준 파이썬 배포본에는 이것에 대한 완전한 예제가 딸려온다. 이 예제는 URLLIB에 기초한다. Tk-기반의 프론트 엔드[2] 모듈인 웹체커(Webchecker)는 파이썬 배포본의 tools 하부디렉토리 아래에서 찾아볼 수 있다. 또다른 파이썬 도구인 린봇(Linbot)은 URLLIB 모듈의 기능을 개선해 준다. 린봇으로 여러분은 웹 사이트의 문제를 모두 해결할 수 있다. 웹 사이트들이 점점 더 복잡해짐에 따라 웹 사이트의 질을 확인하기 위해서는 다른 웹 클라이언트 애플리케이션들이 필요하게 될 것이다.

웹 클라이언트 프로그래밍에는 함정이 하나 있다. 여러분의 프로그램은 페이지의 형식이 조금만 변경되어도 영향을 받는다. 반드시 웹 사이트가 오늘 데이터를 출력하는 방식이 내일도 그대로 유지된다고 장담할 수는 없다. 페이지의 형식이 바뀌면 프로그램도 바뀌어야 한다. 사람들이 XML에 그렇게 흥분하는 이유 중 하나가 바로 이것 때문이다. 웹에서 데이터에 태그를 붙여 의미를 주면 형식은 중요하지 않게 된다. XML 표준이 진화하고 범세계적으로 인정됨에 따라, 훨씬 더 쉽게 그리고 튼튼하게 XML 데이터를 처리하게 될 것이다.

우리가 여기에서 다룬 도구들에는 약간의 제한이 있다. HTTPLIB 모듈과 URLLIB모듈은 클라이언트-기반 작업에는 탁월하지만 오직 한 번에 한 개의 요청만을 처리할 수 있기 때문에 서버를 구축하는데 사용해서는 안된다. 비동기적인 처리방법을 제공하기 위해 샘 러싱(Sam Rushing)은 멋진 도구모음을 구축하였다. 이 도구모음은 asyncore.py 를 포함하여 표준 파이썬 배포본에 딸려 온다. 이 접근법을 사용하는 가장 강력한 예제는 조프(ZOPE)이다. 조프는 애플리케이션 서버로서 샘 러싱(Sam Rushing)의 메듀사 엔진(Medusa engine)을 사용하여 구축한 빠른 http 서버를 포함하고 있다.

다음 기사에서는 XML과 웹 클라이언트 프로그래밍을 어떻게 XMLRPCLIB 모듈에 결합하는지에 대해 논의해볼 생각이다. XML을 사용하면 미어켓(Meerkat) API로부터 더욱 많은 기능을 짜낼 수 있다.
--------------------------------------------------------------------------------
각주
[1] Hyper Text Transfer Protocol
[2] front end: 프론트 엔드
예) GUI는 front end 이며 구현된 기능들은 back end이다.

--------------------------------------------------------------------------------
데이브 워너(Dave Warner)는 Federal Data Corporation사의 선임 프로그래머이자 데이터베이스 관리자(DBA)이다. 그는 P자로 시작하는 언어(Python, Perl, PowerBuilder)로 관계형 데이터베이스에 접근하는 방법을 연구하고 있다.
출처: Hanbit Network

2007년 7월 23일 월요일

[Online Ad③] 온라인 광고시장의 패자는 누구?

지금까지 국내 검색 광고 시장은 오버추어의 주도 하에 성장해 왔다. 그렇지만 구글의 한국 진출과 네이버의 자체 서비스, MS의 잠재력 등 경쟁요소가 늘어나고 있다.

오버추어는 지난 2003년 야후에 인수합병 후 한국, 일본을 제외한 모든 국가에서 YSM(야후서치마케팅)으로 리브랜딩하여 활동 중이다. 즉, 오버추어란 이름은 2개국에서만 남아있다.

한국의 경우, 오버추어코리아의 김제임스우 사장은 야후코리아의 실제적인 총괄 담당자라고 할 수 있으며, 오버추어재팬 대표, YSM 아시아 총괄사장까지 겸임하고 있다. 오버추어는 국내 35,000여 광고주와 네이버, 네이트, MSN, 야후코리아 등 주요 포털과 파트너 네트워크를 구축하고 있다.

이들의 주된 비즈니스 모델은 검색 유료 키워드를 CPC(Cost Per Click) 방식으로 제공하는 것. 그러나 별다른 경쟁 없이 제공되던 CPC는 광고주가 그 효율성, 즉 ROI 측면에서 고려하기 시작하면서 과거의 황금기를 마냥 누릴 수 없는 입장이 됐다. 경쟁자는 많아지고 CPC 광고비가 오버추어의 ‘비딩 프라이스’에 의해 높아지면서 한계를 드러내고 있다.

이러한 한계점을 극복하기 위해 업계는 두 가지 대응책을 내놓고 있다. 하나는 디스플레이 광고 등 검색 광고를 대체할 만한 서비스를 내놓는 것이며, 나머지 하나는 검색 서비스를 고도화하는 것이다.

디스플레이 광고 분야 확보 위한 움직임
디스플레이 광고는 앞서 2부에서 언급했듯이, 온라인 광고의 성장을 위해서 지향해야 하는 비즈니스 모델이다. 그리고 대기업의 참여로 높은 성장 가능성이 보이기 시작했다.

최근 야후는 ‘스마트애즈’라는 새로운 디스플레이 광고 제품을 출시했다. 이는 고객 맞춤형 서비스로 네티즌의 연령, 성별, 지역, 온라인 활동을 고려한 제품이다. 온라인 디스플레이 광고를 주도하고 있는 야후는 스마트애즈를, 온라인 광고 서비스 배급사인 라이트미디어를 인수함에 따라 적극적으로 실행하게 됨으로써 디스플레이 분야의 확실한 우위를 기대하고 있다.

물론 경쟁사들 역시 가만히 있지는 않았다. 검색 광고의 최강자 구글은 온라인 광고회사 더블클릭을, MS는 에이퀀티브를 인수하기로 합의하면서 디스플레이 광고 분야는 폭풍전야의 상황이다. 반면 국내 시장이 이러한 움직임에 민감하지 못한 것은, 역시 2부에서 언급했듯이, 아직 성숙되지 못한 시장 때문이라고 업계는 설명하고 있다.

검색 광고의 고도화 시도
검색 광고 한계 극복을 위한 방법으로 디스플레이 광고의 활성화만 있는 것은 아니다. 검색 광고의 고도화는 디스플레이 광고까지 포함해서 새로운 가치를 만들고자 하는 업계의 고민이 그대로 묻어나고 있다. 또한 이는 인터넷 서비스 및 애플리케이션, 즉 IT기술 발전에 기여하고 있다.

구글이 그 대표주자임은 두말하면 잔소리다. 널리 알려진 대로 구글의 검색 광고 플랫폼은 ‘애드워즈’와 ‘애드센스’로 구분된다. CNET에 의하면 구글은 지난해 이 분야 시장 점유율의 절반 가량을 차지하면 무려 106억 달러의 광고 매출을 올렸다. 이는 애드워즈라는 강력한 플랫폼이 있었기에 가능했다.

구글 애드워즈의 방식은 광고가 아닌 듯 검색 결과에 광고를 노출하는 것이 강점이다. 검색순위 결정에 있어, 사용자의 정보습득 요구와 광고의 연관성을 높였다는 점에서 사용자나 광고주 모두 대체로 만족하고 있다. 기존 CPC 방식이 광고비용만 높으면 최상단에 노출된 것에 비해 합리적이라 여기는 것이다.

이러한 순위결정에서 우수성을 드러냄으로써 구글은 야후보다 늦게 시작했지만, 50만에 달하는 광고주를 확보해, 30만의 야후를 앞설 수 있었다.(광고주 수 2006년 말 기준) 한국의 경우는 많이 다르지만, 점차 이러한 추세를 따라가는 분위기다.

구글코리아의 최명조 세일즈 매니저는 "구글 애드워즈와 같은 방식(부합성(relevancy)을 비딩금액과 함께 고려하는)의 온라인 광고 모델들을 경쟁사들이 최근 잇달아 출시하고 있다"고 주장했다. 즉, NHN이 자체 검색 광고 플랫폼인 ‘클릭초이스’를 내놓은 것이나 오버추어가 ‘파나마’를 내놓은 것이 구글 애드워즈를 모방했다는 것이다.

UCC형 광고 방식도 늘어나...
검색 광고의 고도화는 이른바 UCC형 광고라고 부를 수 있는 ‘애드센스’와 같은 모델이 발달하는 것에서도 찾아볼 수 있다. 웹 2.0에 걸맞게 광고에도 롱테일이 존재하고, 이를 해결하는 것이 UCC형 광고 모델이다.

엄밀하게 말해 UCC라는 단어를 붙이는 것이 적절하지는 않지만, 블로그나 기사가 게재된 페이지의 특정 부분에 광고를 게재하고 그 수익을 게시자와 공유하는 것이기에 이런 표현을 썼다. 최근 웹2.0 사이트에서 UCC 제공자와의 수익공유 모델이 등장하는 것을 심심치 않게 찾아볼 수 있을 것이다.

이러한 모델 또한 다음의 ‘애드클릭스’, 오버추어의 ‘콘텐츠매칭’ 등 비슷한 모델이 등장하고 있다.

야후코리아의 김덕봉 부장은 “콘텐츠매칭은 일부 애드센스와 같은 형태의 상품이다. 그렇지만 애드센스 모델이 수익성이 좋은 것은 아니다”라며 “야후는 여기에 수익성을 향상시키는 방안으로 톱 블로거들을 영입해 수익을 나누는 사업모델을 추진 중이다”라고 밝혔다.

결국 왕좌에는 누가 앉을까?
이외에도 CPC에서 한층 발전한 CPA(Cost Per Action), 즉 실제 구매 시도가 있었을 경우에만 과금하는 형태의 광고 모델 도입도 고려되고 있다. 이미 구글은 CPA 광고 모델인 PPA(Paper Per Action) 베타버전을 내놓기도 했다.

이렇게 치열한 경쟁과 온라인 광고의 발전과정에서 향후 누가 시장을 주도하게 될지 섣불리 판단할 수 없다. 다만 온라인 광고 시장에서 기대 이하의 성적을 내고 있는 야후와 아직은 변방에 위치한 MS, 그리고 꾸준한 구글의 시장 구도는 당분간 지속될 것으로 보인다.

국내의 경우, 오버추어(야후코리아)의 독주 하에 구글이 간섭을 시작하고 있다. 이들은 각각 네이버와 다음이라는 파트너를 내세워 경쟁에 나섰다. 그 이유는 한국시장에서 야후나 구글 자체로서는 아직 파급력이 미미하기 때문이다.

이는 결국 백화점식 포털 서비스에 의존하는 한국 시장의 특수성을 잘 이용하는 쪽이 궁극적으로 왕좌를 차지할 수 있다는 것으로 해석된다.

현재로서는 ▲ 네이버가 자체 광고 플랫폼을 가지고 시장에 진출한 것이나 ▲ 구글-다음과의 광범위한 제휴 ▲ 이미 기득권을 오버추어의 시장 방어라는 ‘Big3’가 향후 시장 활성화에 대비해, 한국 시장에 맞는 준비를 어떻게 마련해 놓느냐가 최대 관전 포인트가 될 것이다. @

[출처 : ZDNet Korea]

[Online Ad②] 검색 광고를 넘어서 브랜드 광고로!

CNET에 따르면 전세계 온라인 광고 시장 규모는 400억 달러이며 매년 20% 가량의 성장률을 보일 것이라고 한다. 그리고 급성장 추세의 검색 광고에 뒤처져 있던 디스플레이 광고가 올해부터 앞서나갈 것이라고 전망했다.



해외 시장의 경우, 기업의 브랜드 이미지 광고를 온라인에 도입하는 사례가 늘고 있다. 이는 온라인 미디어가 차세대 뉴미디어로 광고주들에게 인정을 받기 시작했다는 것을 의미한다. 브랜드 광고는 주로 대기업 수준의 광고주가 디스플레이 광고 형태로 진행한다.



그렇지만 국내의 경우는 조금 다르다. 과거에는 오히려 디스플레이 광고가 차지하는 비중이 더 컸고, 최근 들어 검색광고가 급성장하는 흐름을 여전히 유지하고 있다. 이러한 현상은 해외의 경우와 반비례한다기 보다, 광고주나 사용자의 인식 변환이 조금 느리다고 해석할 수 있다.





국내 온라인광고 시장(자료제공 : 인마협, 오버추어)




인터넷마케팅협회(인마협)와 오버추어가 제공한 자료에 따르면, 2007년 국내 온라인 광고 시장은 약 9,778억원에 달하며 이중 검색 광고는 6,135억원으로 60%를 차지할 것으로 전망했다. 지난 2005년 검색 광고 매출이 전체의 55%를 차지하면 디스플레이 광고를 앞지른 이후 그 성장률이 점차 둔화될 것이라는 분석이 있지만, 여전히 성장을 거듭하고 있다.



디스플레이 광고가 늘어야 시장 파이 확대

이는 여전히 브랜드 광고를 하는 국내의 대형 광고주가 온라인보다는 기존의 오프라인을 선호하고 있음을 드러낸다. 중소규모 광고주로 구성된 검색 광고도 중요하지만, 대기업이 디스플레이 광고로 참여해야 전체 시장의 파이가 커질 수 있다.



야후코리아 미디어세일즈 김덕봉 그룹장은 “외국, 특히 미국의 경우 광고 효과에 대한 수치를 중요시 하는데, 기존 오프라인 매체인 신문이나 TV로는 이를 알 수 없다. 그러나 온라인의 경우 다양한 툴로 인해 수치 확보가 용이하다는 장점이 있다”고 말했다. 즉, 웹에 접하는 사용자가 많아지면서 UV(Unique Visitor)나 PV(Page View) 등 수치를 통해 효과를 가늠할 수 있는 것이다.



단순히 온라인 접근에 대한 수치 확인뿐 아니라, 각종 리서치 자료의 유무에서도 차이가 있다. 국내에서는 인마협 등 소수의 기관만이 관련 자료를 제공하지만, 해외는 수많은 기관에서 ‘온-온프라인 광고의 활용방안과 효과’에 대한 활발한 연구를 통해 리서치 데이터를 확보하고 있어 광고주의 신뢰도 향상에 도움을 주고 있다.



김덕봉 그룹장은 “단편적인 예로 자동차 회사의 마케팅 비용을 보면, 현대차는 온라인 광고비가 전체 광고비의 4% 미만인데 반해, GM이나 포드는 20~30% 수준이다”라고 말했다.



대기업 위주로 온라인 광고 유입 중

그럼에도 불구하고, 업계에서는 국내 온라인 광고 시장의 성장을 비관하지 않는다. 해외에 비해 낮은 수준이지만 브랜드 광고가 온라인으로 서서히 유입되고 있는 분위기다. 다음커뮤니케이션의 최형우 본부장은 “대기업 위주의 크로스미디어(TV+온라인, 신문+온라인 등) 정책은 온라인 광고의 신뢰도를 향상시키고 있으며, 검색 광고의 부족한 부분을 디스플레이 광고가 보완하면서 시장이 발전하고 있다”라고 설명했다.



특히, 삼성전자나 LG전자와 같은 기업은 이미 내부에 ‘온라인 마케팅팀’을 구성하고 온라인에 대한 마케팅 중요성을 인지하고 있는 상황이다. 이들을 포함한 몇몇 대기업들은 온라인에 브랜드 광고를 진행하는 동시에, 실제 구매는 웹 검색을 통해 유발하는 형태의 전략을 이미 구사하고 있다.



또 하나 반가운 점은 브랜드 광고를 하는 기업 영역의 확산이다. 초기에는 대출, 보험, 카드사가 광고주의 대부분이었지만, 최근에는 캘빈클라인, 까르띠에, 벤츠 등 고급 브랜드까지 들어서고 있다. 드디어 온라인을 잠재고객을 유입하는 매체로 인지하기 시작한 것이다.



인터넷마케팅협회의 한 관계자는 “지난 2006년 중반 이후, 온라인 광고주가 모든 산업분야로 확산되는 추세다. 우선 글로벌 기업이 가장 활발하고 국내 대기업들도 이를 따라가고 있다. 이제 주요 광고주들이 온라인을 광고의 공간으로 중요시하기 시작했다”고 말했다. @

[Online Ad①] 온라인 광고에 열광하는 인터넷 기업들

구글, MS, 야후, AOL, 네이버, 다음… 이들의 공통점은 무엇일까? 곰곰이 생각해보면 여러 가지가 나올 수도 있겠지만, 이들 모두가 온라인 광고에 열을 올리고 있다는 점은 단번에 알 수 있을 것이다.

구글, 야후 등 인터넷 포털 기업이 검색 광고나 기타 온라인 광고를 주 수익원으로 하고 있다는 사실은 굳이 설명할 필요가 없다. 그러나 마이크로소프트(MS)가 온라인 광고 시장에 뛰어든 것은 한번 되짚어 볼 필요가 있다.

MS는 지난 5월 광고 서빙 기술을 보유한 온라인 광고업체 ‘에이퀀티브’를 무려 60억 달러라는 최고가에 인수하겠다는 발표를 했다. 이 금액은 MS가 타 업체를 인수했던 가격의 3배 정도라고 하니, 온라인 광고가 어느 정도 투자가치를 갖고 있는지 가늠해 볼 수 있다.

또한 이 금액은 MS에 한 달 앞서 구글이 더블클릭을 인수한 금액의 2배이기도 하다. 구글은 디스플레이 광고 강화를 위해 ‘더블클릭’을 인수했고, 야후 또한 온라인 광고 교환 업체인 ‘라이트 미디어’를 6억8,000만 달러에 인수했다.

인터넷 기업 수익 책임질 매체 ‘온라인’
현 IT업계를 대표하는 글로벌 기업들이 이렇듯 온라인 광고에 열을 올리고 있는 이유는 한 가지. 바로 돈이다.

시대가 시대인 만큼, 사람들은 정보와 오락을 위해 인터넷에 몰리고 있다. 사람들은 이제 뉴스는 물론 TV나 라디오까지 인터넷으로 이용하며, 갖가지 게임에도 열광하고 있다. 컴퓨터/인터넷에 익숙하지 않은 중장년층을 제외한다면, 머지않은 미래의 가장 영향력 있는 매체는 TV나 신문이 아닌 온라인 사이트(모바일 포함)가 될 것이다.

이와 같은 추세를 보면 온라인 시장의 잠재력은 아직 그 끝을 알 수 없을 만큼 무궁무진하다. 때문에 온라인 광고 시장은 인터넷 기업들이 수익을 올릴 수 있는 블루오션이자 점유율 확보를 위한 레드오션을 모두 아우르고 있다.

따지고 보면, 이러한 인수합병의 진원지는 구글이다. 한때 미국 최대의 온라인 기업 AOL이 3년 전에 4억3,500만 달러에 애드버타이징닷컴을 인수한 것도, MS의 사상 최고가의 인수도 광고시장에서의 구글의 독주에서 기인한다. 구글이 자칭-타칭 최고의 기업 MS의 라이벌로 떠오를 수 있었던 것도, 결국 다양한 서비스에 기반한 광고수익이 뒷받침됐기 때문이다.

한국은 대형 포털이 시장 주도
이는 한국에서도 마찬가지다. 시장규모는 작지만 앞으로 매우 흥미진진한 주도권 다툼이 예상된다. 한국은 전세계 온라인 광고 시장 약 400억 달러(약 37조2,000억원) 중 1조원 정도를 차지하고 있다. 그러나 발달된 인프라와 인터넷의 생활화 등을 고려할 때 해외와는 다른 시장을 형성하고 있다.

한국의 온라인 광고 시장은 구글이나 MS가 아닌 네이버와 다음 등 포털의 점유율 순으로 영향력을 갖고 있다. 최근 한국지사를 설립한 구글도, 야후(오버추어)도 포털과 협력하는 것 외에 다른 돌파구를 찾는다는 것은 불가능해 보인다.

기존까지 한국의 검색광고 시장은 오버추어가 주도하고 있었다. 이 회사는 야후에 흡수된 지 꽤 오랜 시간이 지났지만, 위와 같은 이유로 한국 시장에서는 유독 야후-오버추어가 별도 법인으로 운영하고 있다.(일본도 별도로 운영되지만 이는 야후재팬의 지분구조 때문이다)

그리고 구글코리아는 오버추어의 주요 파트너였던 다음을 빼앗아 오면서, 다음, 엠파스 등의 포털을 통해 영역을 넓혀가고 있다. 구글이 한국에서는 워낙 조용했던 터라 다음과의 협력이 어떤 결과를 보여줄 지 기대를 모으고 있다. 또한 현 온라인 광고 분야의 절대강자 네이버는 오버추어와의 협력관계 외에도 자체 검색 광고 플랫폼을 마련해 영업활동을 벌이는 중이다.

이제 온라인 광고에 대한 시각은 단순히 광고 차원에서 머무르지 않는다. 오프라인-온라인으로의 미디어 진화, 사용자를 사로잡는 다양한 신기술의 등장, 웹으로 집중되는 IT 패러다임의 변화를 이끌어 내는 최종목적으로 확대된 것이다. @

[출처:ZDNet Korea]

2007년 7월 12일 목요일

아이폰 애플리케이션 개발자들이 한데 뭉치다


웹 개발자들이 언론의 집중조명을 받으며 세상에 출현한 애플의 신제품 아이폰을 위해 아이폰데브캠프(iPhoneDevCamp)에서 한데 뭉쳤다.

제공: Miriam Olsson/CNET News.com

지난 주말 샌프란시스코 어도비시스템즈에서 열린 이 행사에는 300여명 애플리케이션 개발자들이 참가해 50여 가지에 이르는 아이폰용 애플리케이션과 게임을 선보였다.

제공: Miriam Olsson/CNET News.com

아이폰데브캠프는 자바스크립트가 주는 보안 위협의 극복, 콘텐츠 최적화를 통한 대역폭 최소화 등의 주제를 다루는 여러 개별 회의로 나누어 진행됐다.

제공: Miriam Olsson/CNET News.com

7일아침(미국시간) 수백명의 인파가 하나의 탁 트인 사무실 공간에 모여 있는 것치고는 너무 조용해 의아함을 자아낸다. 이들은 대부분 사파리용 핵(hack)을 만든다든지 하면서 개별적으로 작업에 임하고 있었다. 오후쯤 되어서야 서로 생소한 사람들끼리 팀을 구성해 작업을 하기 시작했다.

제공: Miriam Olsson/CNET News.com

파이어폭스 개발자인 조 휴이트는 ‘틸트(Tilt)’라는 아이폰용 게임을 공동 제작했다. 작은 캐릭터(사진에 이의 원안이 보인다)가 낙하물을 잡는 게임으로 게임 플레이어는 아이폰을 세로에서 가로 방향으로 방향을 바꾸어야 한다.

휴이트는 아이폰데브캠프에서 코드를 함께 공유하고 작업 팀들의 아이폰용 신규 애플리케이션 작업에 도움을 준 공로로 아이폰을 상으로 받았다. 그는 지난 주 초 아이폰 인터페이스용 핵과 캠프 내외부 개발자들에 의해 사용된 템플릿 코드를 제작했다.

제공: Miriam Olsson/CNET News.com

사이트펜(SitePen)의 제이슨 클라인과 아이폰에서 사용 가능하다고 여겨지는 웹 기반 채팅 서비스인 헤이산(Heysan)의 파 린드가 채팅 기능을 아이폰에 최적화하기 위해 함께 작업하고 있다. 이들의 우측에는 베테랑 애플 뉴튼 개발자인 루내틱 에섹스의 모습이 보인다.

제공: Miriam Olsson/CNET News.com

지오피스(gOffice)는 아이폰에서 MS 워드 문서를 생성하고 이를 이메일로 발송하여 저장하는 워드 프로세싱 애플리케이션이다.

제공: Miriam Olsson/CNET News.com

아이폰 데브캠프의 공동주최자인 일명 ‘훨리(Whurely)’로 불리는 윌리엄 헐리(왼쪽)와 이번 캠프에서 감초 역할을 톡톡히 한 크리스토퍼 앨런이 8일오후 핵-어-손(Hack-a-thon)*을 위한 개별 회합의 장을 열었다. 핵-어-손 행사나 아이폰데브캠프는 그 접근방식이 전반적으로 맥핵(MacHack) 행사와 유사하다. 이는 80년대 중반으로 거슬러 올라갈 만큼 전통 있는 행사이고 앨런은 93년 행사를 주관하기도 했다.

50여 개의 팀이 아이폰 애플리케이션을 발표했고 캠프 커뮤니티 웹사이트에 이를 게시했다.

*핵-어-손(Hack-a-thon): 여기서는 여러 사람이 모여 다채로운 아이폰용 핵을 제작 및 발표하는 행사 정도로 풀이할 수 있다.

제공: Miriam Olsson/CNET News.com

한 팀은 아이폰을 투표 도구로 이용하는 방법을 개발했는데 가령 아이폰을 세로로 기울이면 ‘찬성’을 의미하는 녹색이, 가로로 기울이면 ‘반대’를 의미하는 ‘붉은색’이 나타나는 식이다.

아이폰보트(iPhoneVote)라는 이 애플리케이션은 핵-어-손 프리젠테이션 중 투표를 위해 실제로 사용됐다. 그 밖에 아마존 쇼핑 사이트를 휴대형 디바이스에 최적화시키기, 항공기상 관련 애플리케이션, 뉴스 제공, 야구경기 결과 제공, 아이폰을 아이튠즈 리모컨으로 사용하기, 행사 캘린더 등에 관한 프리젠테이션이 있었다.

제공: Miriam Olsson/CNET News.com

이번 행사에서는 코드가 모두에게 공유되었으며 이는 8일 핵-어-손 프리젠테이션에서 자세히 다루어졌다.

제공: Miriam Olsson/CNET News.com

아이폰을 한데 연결해 텍스트, 그림, 색상 등의 스트리밍을 연출하고 있는 모습.

제공: Miriam Olsson/CNET News.com

인텔의 오픈소스 디바라 칭해지는 대니스 쿠퍼는 이 같은 캠프 전통을 지지하는 사람이다. 그는 발매 첫날 아이폰을 구매했고 기능이 아직까지는 완벽하진 않지만 아이폰에 만족스러워하고 있다. 다만 EDGE 네트워크 충돌 문제의 해결과 이메일과 텍스트 작성시 키보드를 가로 방향으로 이용할 수 있길 바라고 있다.

제공: Miriam Olsson/CNET News.com

환한 웃음과 함께 “아이폰”을 외치며 기념촬영하는 모습. @



Miriam Olsson ( CNET News.com )


[ 저작권자 ⓒ ZDNet Korea, CNET Korea,Inc. 무단 전재 및 재배포 금지, ZDNet Korea는 글로벌 IT 미디어 리더 CNET Networks의 브랜드입니다. ]

테이블 속성 변경

테이블 속성 변경

1. 테이블의 필드명을 다른 이름으로 변경
mysql>alter table 테이블명 change 기존필드명 바꿀필드명 바뀐필드타입;

2. 기존 필드의 타입을 다른 타입으로 변경
mysql>alter table 테이블명 modify 필드명 바꿀필드타입;

3. 테이블에 새로운 필드 추가
mysql>alter table 테이블명 add 추가할필드명 필드타입;

*추가할 필드를 기존 테이블의 제일 마지막에 위치
mysql>alter table 테이블명 add 추가할필드명 필드타입;

*추가할 필드를 기존 테이블의 제일 첫번째에 위치
mysql>alter table 테이블명 add 추가할필드명 필드타입 first;

*추가할 필드를 기존 테이블의 중간에 위치
mysql>alter table 테이블명 add 추가할필드명 필드타입 after 생성될필드가 위치할 앞 필드명;

4. 특정한 필드 삭제
mysql>alter table 테이블명 drop 삭제할필드명;

5. 테이블명 변경
mysql>alter table 테이블명 rename 바뀔테이블명;

2007년 7월 9일 월요일

MySQL Table 복구 - Got error 127 from storage engine

1. 에러 메세지

ERROR 1030 (HY000): Got error 127 from storage engine

2. 복구 절차

Analyze Table `Table Name`
Repair Table `Table Name`
3. 예제보기

mysql> SELECT COUNT(A.IDX) AS 'CNT' FROM PRO_QNA_T A WHERE A.TYPE > 0;
ERROR 1030 (HY000): Got error 127 from storage engine
mysql>
mysql>
mysql> Analyze PRO_QNA_T;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'PRO_QNA_T' at line 1
mysql> Analyze Table PRO_QNA_T;
+--------------------+---------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+--------------------+---------+----------+----------+
| ihelpers.PRO_QNA_T | analyze | status | OK |
+--------------------+---------+----------+----------+
1 row in set (0.01 sec)

mysql> Repair Table PRO_QNA_T;
+--------------------+--------+----------+--------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+--------------------+--------+----------+--------------------------------------------+
| ihelpers.PRO_QNA_T | repair | info | Key 1 - Found wrong stored record at 24884 |
| ihelpers.PRO_QNA_T | repair | warning | Number of rows changed from 2187 to 2186 |
| ihelpers.PRO_QNA_T | repair | status | OK |
+--------------------+--------+----------+--------------------------------------------+
3 rows in set (0.17 sec)

mysql> Analyze Table PRO_QNA_T;
+--------------------+---------+----------+-----------------------------+
| Table | Op | Msg_type | Msg_text |
+--------------------+---------+----------+-----------------------------+
| ihelpers.PRO_QNA_T | analyze | status | Table is already up to date |
+--------------------+---------+----------+-----------------------------+
1 row in set (0.00 sec)

mysql> SELECT COUNT(A.IDX) AS 'CNT' FROM PRO_QNA_T A WHERE A.TYPE > 0;
+------+
| CNT |
+------+
| 2186 |
+------+
1 row in set (0.01 sec)

2007년 6월 25일 월요일

HTTP 에러 코드표

400 요청실패
문법상 오류가 있어, 서버가 요청사항을 이해하지 못함, 클라이언트는 수정없이 요청사항을 반복하지 않을 것이다.

401.1 권한 없음 (접속실패)
이 에러는 서버에 로그온 하려는 요청사항이 서버에 들어있는 권한과 비교했을 때 맞지 않을 경우 발생한다. 이 경우, 여러분이 요청한 자원에 접근할 수 있는 권한을 부여받기 위해 서버 운영자에게 요청해야 할 것이다.

401.2 권한 없음(서버설정으로 인한 접속 실패)
이 에러는 서버에 로그온 하려는 요청사항이 서버에 들어있는 권한과 비교했을 때 맞지않을 경우 발생한다. 이것은 일반적을 으로 적절한 www-authenticate head field를 전송하지 않아서 발생한다.

401.3 권한 없음(자원에 대한 ACL에 기인한 권한 없음)
이 에러는 클라이언트가 특정 자원에 접근할 수 없을 때 발생한다. 이 자원은 페이지가 될 수도 있고 , 클라이언트의 주소 입력란에 명기된 파일일 수도 있다. 아니면 클라이언트가 행당 주소로 들어갈 때 이용되는 또 다른 파일일 수도 있다. 여러분이 접근할 전체 주소를 다시 확인해 보고 웹 서버 운영자에게 여러분이 자원에 접근할 권한이 있는지를 확인해 본다.

401.4 권한 없음(필터에 의한 권한 부여 실패)
이 에러는 웹 서버가 서버에 접속하는 사용자들을 확인하기 위해 설치한 필터 프로그램이 있음을 의미한다. 서버에 접속한는 데 이용되는 인증 과정이 이런 필터 프로그램에 의해 거부되었다.

401.5 권한 없음(ISA PI/CGI 애플리케이션에 의한 권한부여 실패)
이 에러는 여러분이 이용하려는 웹 서버의 어드레스에 ISA PI나 CGI프로그램이 설치되어 있어 사용자의 권한을 검증하고 있음을 의미한다. 서버에 접속하는 데 이용되는 인증 과정이 이 프로그램에 의해 거부되었다.

403.1 금지(수행접근 금지)
이 오류는 CGI나 ISAPI,혹은 수행시키지 못하도록 되어있는 디렉토리 내의 실행 파일을 수행시키려고 했을 때 발생한다.

403.2 금지(읽기 접근 금지)
이 에러는 브라우저가 접근한 디렉토리에 가용한 디폴트 페이지가 없을 경우에 발생한다. 아니면 Eecute나 Script로 분한이 부여된 디렉토리에 들어있는 HTML페이지를 보려했을 때 발생한다.

403.4 금지(SSL 필요함)
이 에러는 여러분이 접근하려는 페이지가 SSL로 보안유지 되고 있는 것일 때 발생한다. 이것을 보기 위해서 여러분은 주소를 입력하기 전에 먼저 SSL을 이용할 수 있어야 한다.


403.5 금지 (SSL 128필요함)
이 에러는 접근하려는 페이지가 SSL로 보안유지 되고 있는 것일 때 발생한다. 이 자원을 보기 위해서는 여러분의 브라우저가 SSL의 행당 레벌을 지원해야 한다. 여러분의 브라우저가 128비트의 SSL을 지원하는 지를 확인해 본다.

403.6 금지(IP 주소 거부됨)
이 에러는 서버가 사이트에 접근이 허용되지 않은 IP주소를 갖고 있는데, 사용자가 이 주소로 접근하려 했을 때 발생한다.

403.7 금지(클라이언트 확인 필요)
이 에러는 여러분이 접근하려는 자원이 서버가 인식하기 위해 여러분의 브라우저에게 클라이언트 SSL을 요청하는 경우 발생한다. 이것은 여러분이 자원을 이용할 수 있는 상용자임을 입증하는데 사용된다.

403.8 금지 (사이트 접근 거부됨)
이 에러는 웹 서버가 요청사항을 수행하고 있지 않거나, 해당 사이트에 접근하는 것이 허락되지 않았을 경우 발생한다.

403.9 접근 금지(연결된 사용자수 과다)
이 에러는 웹서버 BUSY 상태에 있어서 여러분의 요청을 수행할수 없을 경우에 발생한다. 잠시 후에 다시 접근해 보도록 한다.

403.10 접근금지(설정이 확실 하지 않음)
이 순간 웹 서버의 설정쪽에 문제가 있다.

403.11 접근금지(패스워드 변경됨)
이 에러는 사용자 확인단계에서 잘못된 패스워드를 입력했을 경우 발생한다. 페이지를 갱신한 후 다시 시도해 본다.

403.12 접근금지(Mapper 접근 금지됨)
여러분의 클이언트 인증용 맵이 해당 웹 사이트에 접근하는 것이 거부되었다. 사이트 운영자에게 클라이언트 인증 허가를 요청한다. 또한 여러분은 여러분의 클라이언트 인증을 바꿀 수도 있다.

404 발견안됨
웹 서버가 요청한 파일이나 스크립트를 찾지 못했다. URL을 다시 잘 보고 주소가 올바로 입력되었는지 확인해본다.

405 메쏘드 허용안됨
Request 라인에 명시된 메쏘드를 수행하기 위해 해당 자원의 이용이 허용되지 않았다. 여러분이 요청한 자원에 적절한 MIME 타입을 갖고 있는지 확인해 본다.

406 받아들일 수 없음
요청 사항에 필요한 자원은 요청 사항으로 전달된 Acceptheader에 따라 "Not Acceptable"인 내용을 가진 Response 개체만을 만들 수 있다.

407 대리(Proxy) 인증이 필요함
해당 요청이 수행되도록 proxy 서버에게 인증을 받아야 한다. proxy서버로 로그온 한 후에 다기 시도해 본다.

412 선결조건 실패
Request-header field에 하나 이상에 선결조건에 대한 값이 서버에서 테스트 결과 FALSE로 나왔을 경우에 발생한다. 현재 자원의 메타-정보가 하나 이상의 자원에 적용되는 것을 막기 위한 클라이언트 선결조건이 의도되어졌다.

414 요청한 URI가 너무 길다
요청한 URI가 너무 길어서 서버가 요청 사항의 이행을 거부했다. 이렇게 희귀한 상황은 아래와 같은 경우에만 발생한다. 클라이언트가 긴 탐색용 정보를 가지고 POST 요청을 GET으로 부적절하게 전환했다. 클라이언트가 Redirection문제를 접하게 되었다. 서버가, 몇몇 서버가 사용하고 있는 요청한 URI 를 읽고 처리하는 고정된 길이의 메로리 버퍼를 이용해 보안체계에 들어가려는 , 클라이언트에 의한 공격을 받고 있다.

500 서버 내부 오류
웹 서버가 요청사항을 수행할 수 없다. 다시 한 번 요청해 본다.

501 적용안됨
웹 서버가 요청사항을 수행하는 데 필요한 기능을 지원하지 않는다. 에러가 발생한 URL을 확인한 후에, 문제가 지속될 경우에는 웹 서버 운영자에게 연락한다.

502 게이트웨이 상태 나쁨
Gateway나 proxy로 활동하고 있는 서버가 요구 사항을 접수한 upstream 서버로부터 불명확한 답변을 접수 했을 때 발생한다. 만약 문제가 지속된다면 웹 서버 운영자와 상의해 본다.

2007년 6월 5일 화요일

비트 레이트 (CBR, VBR, ABR, SBC), 샘플 레이트, 사운드의 샘플링 개념

1. 비트 레이트(Bit Rate)
비트 레이트는 비트(bit) + 레이트(rate, 비율)의 합성어로, 정보의 비율을 뜻하는 것으로 1초에 얼마나 많은 데이터들이 흘러가는 가를 나타내는 것이다. 데이터 량이 많을 수록 즉, 숫자가 커질 수록 소리는 원음에 가깝다. 하지만 비트 레이트를 많이 집어 넣으면 넣을 수록 비트의 수는 그만큼 커지게 되므로 용량 또한 더 커지게 된다. 비트 레이트는 고정(CBR)과 가변(VBR)으로 나뉜다.

- CBR(Constant Bit Rate) - 고정 전송률
이 방식은 고정 비트 레이트로써 처음부터 끝까지 고정된 비트 레이트를 사용해서 압축을 한다. 보통 VCD(Video CD)의 경우가 그런데 이것은 초당 1150 kbit를 사용해서 모든 프레임을 압축한다. 이 방식의 장점은 인코딩(Encoding)을 하는데 걸리는 시간이 짧은 반면 처음부터 끝까지 항상 고정된 비트레이트 만을 사용하기 때문에 움직임이 많은 곳에서는 화질 저하가 생긴다. 그러므로 움직임이 많은 동영상(스포츠, 액션 영화 등)에는 사용상 부적절함이 있다.
Divx 3.x 4.x 코덱은 CBR이 아닌 VBR 방식을 사용하고 있다.

- VBR (Variable Bit Rate) - 가변 전송률
이 방식은 크게 세가지 방식으로 압축을 행하는데 Average(보통), Max(최대), Min(최소)으로 나뉜다. 평상시에는 보통(Average)의 비트만을 사용하다가 움직임이 빠른 곳에서는 최대(Max) 비트를 사용하고 움직임이 없는 곳에서는 가장 낮은 최소(Min) 비트만을 사용해서 압축을 한다. 그러므로 경우에 따라서 CBR 방식에 비해 더 작은 용량에 더 좋은 화질을 만들어 내므로 더 효율적이라고 볼 수 있다. 하지만 VBR방식은 압축할려는 비디오 전체를 한번 읽고 처음부터 다시 압축을 행하기 때문에 CBR 방식에 비해 보통 압축하는데 걸리는 시간이 두배 이상 걸리게 된다.
Divx 코덱은 기본적으로 모두 VBR을 사용하고 있다.

- ABR(Average Bit Rate) - 평균 전송률
VBR 방식이 평균(Average), 최대(Max), 최소(Max)를 사용자가 지정해서 압축을 한다면 ABR 방식은 평균이 되는 수치만을 적용해 주면 자동으로 그 변동폭을 조절하여 압축을 하는 방식이다. 이 방식은 주로 DivX 코덱의 VBR 방식과 유사하며, 그런 이유(비트 레이트의 변동폭이 크지 않기 때문에)로 요즘은 DivX 코덱의 VBR 방식을 개선하여 SBC라는 인코딩 방식을 통해 압축을 하기도 한다.
이런 방법은 주로 MP3 오디오 인코딩에 적용된다.

- SBC(Smart Bitrate Control)
Virtual Dub의 변형인 Nandub 이나 Gordian Knot을 사용해 좀 더 정교하게 DivX(버전 3.11 Alpha) 인코딩을 하는 방식을 말한다. 그러므로 CBR 이나 VBR에 대응하는 전혀 새로운 방식의 인코딩 방식이 아닌 DivX 코덱을 사용해서 최대한 용량 대비 화질을 구현하기 위해 만들어진 인코딩 방법이다. 요즘 인터넷 등에서 떠도는 DVDRip(DVD에 있는 영화를 추출한다는 의미)의 DivX 영화를 보면 일반적인 DivX 영화가 있고 최근에 들어선 SBC DivX 영화라고 되어 있는 것들이 있는데 이런 영화들이 바로 이 방식을 사용해서 압축되어진 영화라는 뜻이다. 하지만 SBC 방식의 인코딩법은 보통 한번의 가상 인코딩 과정을 거친 후에 실제 인코딩이 시작되기 때문에 보통 일반적인 DivX 인코딩 보다 약 2배 이상의 시간이 소비되고 프로그램의 사용법 또한 쉽지 않기 때문에 전문적인 지식이 없는 일반인들이 쉽게 제작하기에는 다소 어려운 점이 있다.

2. 샘플 레이트
샘플 레이트는 아날로그 음성 데이터를 디지털로 변환할 때 1초 동안 나타낼 수 있는 음의 샘플링 비율 단위로 수치가 높을 수록 원음에 가깝다.

3. 사운드의 샘플링 개념
소리 신호는 아날로그 신호이므로, 컴퓨터에서 소리 신호를 효과적으로 처리하기 위해서는 아날로그 신호를 디지털 신호로 변조하는 일이 필요하다. 사운드 카드에서 처리하는 사운드는 디지털 데이터로 샘플링 된 것이다. 여기서 샘플링을 한다는 것은 신호를 짧은 일정 시간 간격으로 연속적으로 측정하여 각각의 진폭을 숫자로 표현하는 것을 말한다. 따라서 주기를 얼마나 크게 하느냐, 즉 얼마나 샘플링을 자주 하는 가에 따라 원래의 아날로그 신호를 얼마나 정확하게 표현할 수 있는지의 여부가 달려 있다.

사운드 샘플링의 대표적인 방법인 PCM 방식으로 설명을 하면 이렇다.
PCM 방식으로 디지털화 하는데 고려할 중요한 사항은 샘플링 비율과 샘플의 크기 표현이다. 샘플링 비율은 시간 폭을 말하는데 헤르쯔(Hz) 단위로 나타내며 일반적으로 샘플링 될 주파수의 2배 이상의 샘플링 비율을 가져야만 음의 표현이 가능하다. 예를 들어 11.025KHz라 하면 1초에 11,025개의 작은 시간 단위로 나누었다는 의미이다.

샘플의 크기 표현은 소리의 크기를 몇 비트의 크기로 표현하는가 하는 문제이다. 8비트는 256가지로 소리의 크기를 구분할 수 있으며, 16비트는 65,536가지로 소리의 크기를 구분할 수 있다. 16비트로 표현하면 더욱 정확한 소리의 표현이 가능하나 저장 공간이 커지는 단점이 있다.


출처:http://cafe.naver.com/devctrl.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=4113

2007년 5월 31일 목요일

MYSQL 함수 모음

1) 숫자 함수
ABS(X) : X 에 해당하는 절대 값을 돌려준다.
SIGN(X) : X의 값의 부호 값을 돌려 준다.(-1 : 음수, 0 : 0, 1 : 양수)
MOD(N,M) : N을 M으로 나눈 값의 나머지를 돌려 준다.
FLOOR(X) : 실수 X 값의 소수점 이하의 값은 버림을 한 정수 값을 돌려 준다.
CEILING(X) : 실수 X 값의 소수점 이하의 값을 올림을 한 정수 값을 돌려 준다.
ROUND(X,D) : 실수 X 값에서 소수점에서 D + 1번째에 해당하는 값을 올림한 값을 돌려 준다. POWER(X,Y) : X의 값을 Y번 곱한 값을 돌려 준다. RAND() : 0에서 1 사이의 숫자를 랜덤하게 발생시겨 돌려준다.

SELECT abs(-2),abs(2),sign(-45),sign(0),sign(34),mod(23,7);
SELECT floor(1,234),ceiling(1,234),round(2,49),round(2,51); SELECT power(3,2),power(3,3),rand();


문자열함수
2) 문자열 함수
CHAR(N,...) : N(1-256의 정소)값의 아스키코드를 해당 문자로 출력한다. CONCAT(str1,str2,...) : 각각의 str1,str2,...등을 하나의 스트링으로 돌려 준다. 단, NULL 이 있으면 NULL 을 출력한다.
CONCAT_WS(separator, str1, str2,...) : 각각의 str1,str2,...등을 separator을 구분자로 사용하여 하나의 스트링으로 출력한다.
LENGTH(str) : str의 문자의 길이를 출력한다.

SELECT char(48),char(76),concat(('My','S','ql'),concat('My',NULL,'Sq;');
SELECT concat_ws(',','My',NULL,'Sql',' ','is',' ','Good'); SELECT length('mysql'),locate('bar','foobarbar');


LOCATE(substr,str) : str에서 substr이 위치한 첫번째 위치를 정수 값으로 출력한다.
LEFT(str,len) : str에서 지정해준 자릿수 len만큼 왼쪽에서부터 문자열을 출력한다.
RIGHT(str,len) : str에서 지정해준 자릿수 len만큼 오른쪽에서부터 문자열을 출력한다.
SUBSTRING(str,pos,len) : 문자열 str에서 특정 시작위치 pos에서 지정된 길이 len만큼 문자를 출력한다.
LTRIM(str),RTRIM(str),TRIM(str) : str의 왼쪽,오른쪽,혹은 양쪽 모두의 공백 문자를 제거해 준다.

SELECT left('mysql is good',3),right('mysql is good',3); SELECT substring('mysql is good',1,5);
SELECT ltrim(' mysql'),rtrim(mysql '),trim(' mysql ');


SPACE(N) : N개 만큼의 공백 문자를 만들어 출력한다.
REPLACE(str,from_str,to_str) : 문자열 str에서 특정문자 from_str을 특정 문자 to_str로 바꾸어 출력한다.
REPEAT(str,count) : 문자열 str을 count 갯수만큼 반복하여 반복한 값을 출력한다.
REVERSE(str) : 문자열 str을 역으로 출력 한다.
INSERT(str,pos,len,newstr) : 문자열 str에서 특정 위치 pos에서 특정 길이 len 만큼을 newstr문자열로 바꾸어 출력한다.

SELECT concat('a',space(6),'a');
SELECT replace('mysql is good','is','very'),repeat('a',3); SELECT reverse('mysql'),insert('Quadratic',3,4,'What');


LCASE(str) : 문자열 str을 소문자로 바꾸어 출력한다.
UCASE(str) : 문자열 str을 대문자로 바꾸어 출력한다.

SELECT lcase('MYSQL'),ucase('mysql);


날짜시간함수
3) 날짜, 시간 함수
DAYOFWEEK(date) : 해당날짜의 요일값을 출력한다.(1=일요일,2=월요일,3=화요일,...,7=토요일)
WEEKDAY(date) : DayOfWeek() 함수와 같지만 요일값이 다르다.(0=월요일,1=화요일,...,6=일요일)
DAYOFMONTH(date) : 해당날짜의 날(1-31) 값을 출력한다.
DAYOFYEAR(date) : 일년중 몇번째 날(1-366)인지를 출력한다.
MONTH(date) : 해당 날짜의 달(1-12) 값을 출력한다.
DAYNAME(date) : 해당 날짜의 요일 값을 스트링으로 출력한다.

SELECT dayofweek('2003-02-22'),weekday('2003-02-23');
SELECT dayofmonth('2003-02-22'),dayofyear('2003-02-23'); SELECT month('2003-02-22),dayname('2003-02-23');


MONTHNAME(date) : 해당 날짜의 달 값을 스트링으로 출력한다.
QUARTER(date) : 총 4분기중 해당 날짜의 분기 수 값을 출력한다.
WEEK(date,first) : 해당날짜가 1년중 몇번째 주인지를 출력한다.
YEAR(date) : 해당 날짜의 년도 값을 출력한다.
YEARWEEK(date,first) : 해당 날짜의 년도와 1년중 몇번째 주인지를 출력한다.
HOUR(time) : 해당 시간의 시 값을 출력한다.

SELECT monthname('2003-02-22'),quarter('2003-02-23');
SELECT week('2003-02-22'),year('2003-02-23'); SELECT yearweek('2003-02-22'),hour('10:22:32');


MINUTE(time) : 해당 시간의 분 값을 출력한다.
SECOND(time) : 해당 시간의 초 값을 출력한다.
PERIOD_ADD(P,N) : P(YYMM or YYYYMM)값에서 N 달을 뺀 값을 출력한다.
PERIOD_DIFF(P1,P2) : P1(YYMM or YYYYMM)과 P2(YYMM or YYYYMM)의 달 차이를 출력한다.
TO_DAYS(date) : 0년 부터 date까지의 날 수를 출력한다.
FROM_DAYS(N) : N(날)에 해당하는 날짜를 출력한다.

SELECT minute('10:22:32'),second('10:22:32');
SELECT period_add(200302,3),period_diff(0302,200209); SELECT to_days(20030222),from_days(731633);


DATE_FORMAT(date,format) : date의 날짜 값을 원하는 format 값으로 바꾸어 출력한다.
TIME_FORMAT(time,format) : time의 시간 값을 원하는 format 값으로 바꾸어 출력한다.
CURDATE() : 현재의 날짜 값을 출력한다.
CURTIME() : 현재 시간을 출력한다.
NOW() : 현재 시스템의 날짜와 시간을 출력한다.

SELECT date_format('2003-02-22 22:23:00','%D %y %a %d %m %b %j');
SELECT time_format('22:23:00','%H %k %h %i %I %r %p %s %S'); SELECT curdate(),curtime(),now();


제어함수
4) 제어 함수
1) ~ 3)까지의 함수들은 이름만 들어도 대강은 어떤 함수일 거란 것을 예상 할 것이다. 그럼 제어 함수란 무엇인가. 이들 함수는 일반적인 프로그래밍 언어에서의 조건문과 같은 역할을 하는 함수들이다. 종류로는 IsNULL,NULLIF,IF,CASE등이 있으며 이들 함수로 인해 SQL문 안에서 값들을 제어 할 수가 있다.

IFNULL(expr1,expr2) : expr1 값이 널이면 expr2값이 출력이 되는 함수
NULLIF(expr1,expr2) : expr1 값과 expr2값이 같으면 NULL이 출력이 되고 다르면 expr1 값이 출력되는 함수
IF(expr1,expr2,expr3) : expr1 값이 참이면 expr2 값이 출력되고 거짓이면 expr3값이 출력되는 함수
CASE value WHEN [compare-value] THEN result [WHEN [compare-value] THEN result ...] [ELSE result] END : value 값이 WHEN 다음의 compare-value값과 같으면 THEN 다음의 result 값을 출력하는 함수
SELECT IFNULL(NULL,2),IFNULL(1,2),IF(1 > 0,1,0),IF(1 < id =" 'kim';" id =" a.ID)" id =" a.ID;">등을 서브쿼리(SubQuery)에서도 지원하고 있다. 이건 오픈 소스 데이터 베이스의 한계로 앞으로 이들 오픈 소스 데이터 베이스도 역시 지원을 할 것이다.

[오라클] 기본팁
<< 오라클 >>** 오라클 사용시 "commit;" 명령어 사용함 **
1. [테이블의 필드 확인] - desc 테이블명;-예) desc cybedu_board01;
2. [날짜 표현] - sysdate (MS-SQL에서는 getdate())-예) select sysdate from cybedu_section;
3. [중간 글 틀렸을때 수정] - c옵션은 변환, r옵션은 변환값으로 재실c행
예) SQL> 22* where substring(convert(varchar2(20),sysdate,120),1,10) >= 2004-07-29SQL> c/varchar2/varchar2* where substring(convert(varchar(20),sysdate,120),1,10) >= 2004-07-29SQL> 33* and substring(convert(varchar2(20),sysdate,120),1,10) <= 2004-08-05SQL> c/char2/char3* and substring(convert(varchar(20),sysdate,120),1,10) <= 2004-08-05SQL> r1 select popWidth, popHeight, popFlag from cybedu_popup2 where substring(convert(varchar(20),sysdate,120),1,10) >= 2004-07-293 and substring(convert(varchar(20),sysdate,120),1,10) <= 2004-08-054* order by 2004-07-29 desc, 2004-08-05 desc, popsn descwhere substring(convert(varchar(20),sysdate,120),1,10) >= 2004-07-29
=> 오라클에서는 substring -> substr, convert사용안함, varchar -> to_char로 사용* 아래는 문제 해결 구문 *
sql = "select popWidth, popHeight, popFlag from cybedu_popup"; sql = sql + " where substr(to_char(sysdate,'YYYY-MM-DD'),1,10) >= popstartday";sql = sql + " and substr(to_char(sysdate,'YYYY-MM-DD'),1,10) <= popendday";sql = sql + " order by popstartday desc, popendday desc, popsn desc"; 4. oracle에서 left outer join을 하시려면[MY-SQL]select aa.day,aa.count,bb.apply from (select day,count from tblCount where year='2004' and month='06') aa left outer join (select day, count(*) as apply from tblApply where year='2004' and month='06' and Deliverystate='신청접수' group by month,day) bb on aa.day = bb.day; [오라클]select aa.day,aa.count,bb.apply from (select day,count from tblCount where year='2004' and month='06') aa , (select day, count(*) as apply from tblApply where year='2004' and month='06' and Deliverystate='신청접수' group by month,day) bb where aa.day = bb.day(+) <--이런식으로 써야 outer join이 걸립니다... 5. 오라클에서 컬럼 자동 증가 하기create table cybedu_message ( msgid integer not null, /* 일련번호*/msgSendId varchar2 (10), /*쪽지보낸사람 ID*/ ~ ~ ~msgDate date, /* 쪽지보낸 날짜*/~ ~ ~msgFlagR varchar2 (2), /* 받은쪽지함에 보여지는 여부*/ primary key ( msgid ) ) ; create sequence msgid_seq; ==> 자동증가 (ms-sql: identity(1,1))
6. **** 오라클 기본 문법 ****삭제: delete from 테이블 이름 where 조건절 ;

[MS-SQL] 기본 사용법
1. CEILING -> 소숫점 아래수를 반올림해서 정수값 돌려줌
SELECT Count(*),CEILING(CAST(Count(*) AS FLOAT)/보여줄 페이지수)FROM 테이블명 WHERE search_word LIKE '%SearchString%'
rs.Open strSQL, dbcon
intTotalCount = rs(0) ' 총 페이지 수 (검색어가 있을때, 없을때)intTotalPage = rs(1) ' 보여줄 페이지 수의 값(intPageSize가 10이므로 10페이지씩 몇개를 보여줄지의 수)rs.Close
2. Top 숫자 -> 상위의 "숫자"만큼 뿌려줌
strSQL = "SELECT Top " & intNowPage * intPageSize & " brdnum, brdtitle, brdname, writedatetime, brdcount "strSQL = strSQL+ "FROM gong_news_board WHERE brdstate = '02' "if search_word <> "" thenstrSQL = strSQL & " AND " & search_word & " LIKE '%" & SearchString & "%'"end ifstrSQL = strSQL & " ORDER BY brdnum DESC"
3. ISNULL 사용법
예> SELECT EMPNO, ENAME, DEPTNO FROM EMP;
EMPNO ENAME DEPTNO SALARY--------------------------------------------01001 김갑돌 101 NULL01002 이몽룡 102 1000001003 홍길동 NULL NULL01004 고인돌 NULL 500001005 손오공 111 NULL
이러한 경우,
SELECT EMPNO, ENAME, ISNULL(DEPTNO,'999'), ISNULL(SALARY,0)FROM EMP;
EMPNO ENAME DEPTNO SALARY--------------------------------------------01001 김갑돌 101 001002 이몽룡 102 1000001003 홍길동 999 001004 고인돌 999 500001005 손오공 111 0
이와 같이 얻으실수 있습니다.
4. sql문 case -> if 문으로 변환
[case 문] [if 문]
select m.[번호] select m.[번호], m.[이름] , m.[이름], [회원구분] = , [회원구분] =case if ( when m.[번호] in ( m.[번호] in (select [번호] select [번호]from [정회원] as r ---> from [정회원] as rwhere r.[번호] = m.[번호] where r.[번호] = m.[번호]) )then '정' , '정'else '준' , '준')end , m.[전화번호] , m.[전화번호]from [회원] as m from [회원] as morder by m.[번호] order by m.[번호]
5. ** 해당 날짜 사이의 값 가져오기 **
select count(distinct lecNo) from cybedu_curriculum, cybedu_course, cybedu_section, cybedu_lecture left join cybedu_train on ( lecNo = traNo )where convert(varchar(10),getdate(),120) between secStartregist and secEndregistand secNo=lecSecno and crsCode=lecCrscodeand curCode = crsCurcode and curCode = 'curCode' and secFlag='0'
=> 설명 : from 뒤의 테이블과 join 뒤의 테이블을 left join해서(lecNo = traNo) 값중에서between뒤의 시작날짜와 종료날짜 사이의 값을 가져오라는것..
(아래 sql문은 업그레이드 한 것인거 같네여~)..위랑 같은 내용
select count(distinct lecNo) from cybedu_curriculum, cybedu_course, cybedu_section, cybedu_lecture left join cybedu_train on ( lecNo = traNo ) where convert(varchar(10),getdate(),120) between secStartregist and secEndregistand secNo=lecSecno and crsCode=lecCrscodeand curCode = crsCurcode and secFlag='secFlag' and curcode <> 'offline'
6. delete 구문delete 테이블명 where 조건문
7. update 구문update 테이블명 set 바꿀구문 where 조건구문

[MS-SQL] 중요팁2

----------------------------------<<>>-----------------------------------
1. 기본 쿼리sp_spaceused : DB사용자 정보 보여줌sp_dboption : 가능한 DB 옵션들sp_helpdb : 각DB이름,사이즈,owner등을 보여줌sp_helpdb 디비명 : 디비의 설명
2. 다른 DB의 테이블 불러서 사용하기- 우선 sql서버 엔터프라이즈 관리자에서/ENT01/users/ 사용자를 추가한다.- DB -> ENT01, 111
- 111에서 ENT01의 board14테이블 사용하려면
ex) select * from ENT01.111.board14 -> select * from 해당DB.테이블소유자명.테이블명

[MS-SQL] 중요팁
1. 오픈 쿼리 사용법
* 링크드 리스트가 설정이 되어 있어야 오픈쿼리 사용됨.(MS-SQL에서 사용됨)
------------------------------------ (사용예) ---------------------------------------/*sql = "select convert(varchar(20),user_id), convert(varchar(20),name), convert(varchar(20),jumin)";sql = sql + " from OPENQUERY(jejunet,'SELECT user_id, jumin, name FROM member_table') as member_table where (convert(varchar(20),name) = ?) and (substring(convert(varchar(20),jumin),1,6) = ?)";
pstmt = con.prepareStatement(sql);pstmt.setString(1,name);pstmt.setString(2,pass);rs = pstmt.executeQuery();if(rs.next()){student.setId(rs.getString(1)); */
sql = "select korname, usrjumin from cybedu_userinfo where (korname = ?) and (usrjumin = ?)"; //out.print(sql);
pstmt = con.prepareStatement(sql);pstmt.setString(1,name);pstmt.setString(2,pass);rs = pstmt.executeQuery();if(rs.next()){student.setId(rs.getString(1));--------------------------------------------------------------------------------------
2. 병렬 처리 사용 방법
* 생성시 같이 정의 create table line_item (item_no number(7), item_name varchar(20), ... ) parallel 20;create index item_index on line_item (item) parallel 20;
* 이미 작성된 오브젝트에 대한 병렬처리 alter table line_item parallel 20;alter index item_index rebuild parallel 20;응용프로그램의 수정없이 즉시 사용
* 해당 SQL만 병렬로 처리 : Hint 기능 사용 select /*+ parallel(line_item,20) */ item_name, ... from line_item, products .....

각종 DBMS JDBC 드라이버 셋팅법 정리
//********** 각 경우별 드라이버 연동하기 **************/
** JDK jdbc-odbc driver (Type1) **연결 URL : "jdbc:odbc:"드라이버 클래스 : sun.jdbc.odbc.JdbcOdbcDriver
** Oracle thin driver (Type4) **연결 URL : "jdbc:oracle:thin:@:port:"드라이버 클래스 : oracle.jdbc.driver.OracleDriver
** Oracle oci driver (Type2) **연결 URL : "jdbc:oracle:oci:@"드라이버 클래스 : oracle.jdbc.driver.OracleDriver
** Sybase jConnect driver (Type2) **연결 URL : "jdbc:sybase:Tds::"드라이버 클래스 : com.sybase.jdbc2.jdbc.SybDriver
** Informix JC1 driver (Type4) **연결 URL : "jdbc:informix-sql://:/:INFORMIXSERVER"드라이버 클래스 : com.informix.jdbc.IfxDriver
** mSQL Imaginary JDBC driver (Type4) **연결 URL : "jdbc:msql://:/"드라이버 클래스 : com.imaginary.sql.msql.MsqlDriver
** Postgres driver (Type4) **연결 URL : "jdbc:postgresql://:/"드라이버 클래스 : postgresql.driver
** MM MySQL driver (Type4) **연결 URL : "jdbc:mysql://:/"드라이버 클래스 : org.git.mm.mysql.Driver
mysql은 JConnector 3.0 부터는 com.mysql.jdbc.Driver
연결 URL 은 jdbc:mysql://localhost/dbname?Unicode=true&characterEncoding=EUC_KR
같이 인코딩 타입을 직접 줌으로써 한글 변환문제에 좀더 쉽게 해결할 수 있음.

// ******************************Connected To IBM AS/400
Class.forName("com.ibm.as400.access.AS400JDBCDriver"); com = Driver.Manager.getConnection("jdbc:as400://10.20.30.40/testlib;user=user;password=pass");
// ******************************Connected To Unisql
Class.forName("unisql.jdbc.driver.UniSQLDriver"); con = Driver.Manager.getConnection("jdbc:unisql:10.20.30.40:43300:demodb:::", "user","pass");
// ******************************Connected To Jdbc-Odbc Type - 1 Driver
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); // con = DriverManager.getConnection("Jdbc:Odbc:dsnname","userid","password"); con = DriverManager.getConnection("jdbc:odbc:Driver={SQL Server};Server=servername;Database=pubs","userid","password");
// ******************************Connected To Ms-Access JDBC ODBC Driver .
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); con = DriverManager.getConnection("Jdbc:Odbc:dsnname","",""); // con = DriverManager.getConnection("jdbc:odbc:Driver={MicroSoft Access Driver (*.mdb)};DBQ=G:/admin.mdb","","");
// ******************************Connected To Ms-Access Type-3 Driver.
Class.forName ("acs.jdbc.Driver"); String url = "jdbc:atinav:servername:5000:C:\admin.mdb"; String username="Admin"; String password=""; Connection con = DriverManager.getConnection(url,username,password);
// ******************************Connected To Microsoft SQL.
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver"); con = DriverManager.getConnection("jdbc:microsoft:sqlserver://servername:1433","userid","password");
// ******************************Connected To Merant.
Class.forName("com.merant.datadirect.jdbc.sqlserver.SQLServerDriver"); con = DriverManager.getConnection("jdbc:merant:sqlserver://servername:1433;User=userid;Password=password");
// ******************************Connected To Atinav SqlServer.
Class.forName ("net.avenir.jdbc2.Driver"); con= DriverManager.getConnection("jdbc:AvenirDriver://servername:1433/pubs","userid","password");
// ******************************Connected To J-Turbo.
String server="servername"; String database="pubs"; String user="userid"; String password="password";
Class.forName("com.ashna.jturbo.driver.Driver"); con= DriverManager.getConnection("jdbc:JTurbo://"+server+"/"+database,user,password);
// ******************************Connected To jk Jdbc Driver.
String url= "jdbc:jk:server@pubs:1433"; Properties prop = new Properties(); prop.put("user","userid");//Set the user name prop.put("password","password");//Set the password
Class.forName ("com.jk.jdbc.Driver").newInstance(); con = DriverManager.getConnection (url, prop);*/
// ******************************Connected To jNetDirect Type - 4 Driver
String sConnect = "jdbc:JSQLConnect://127.0.0.1/database=pubs&user=userid&password=password"; Class.forName ("com.jnetdirect.jsql.JSQLDriver").newInstance(); Connection con= DriverManager.getConnection(sConnect);
// ******************************Connected To AvenirDriver Type - 4 Driver
// String url= "jdbc: AvenirDriver: //servername:1433/pubs"; // java.util.Properties prop = new java.util.Properties (); // prop.put("user","userid"); // prop.put("password","password");
Class.forName ("net.avenir.jdbc2.Driver"); System.out.println(" Connected To AvenirDriver Type - 4 Driver"); con= DriverManager.getConnection("jdbc:AvenirDriver://servername:1433/pubs","userid","password");
// ******************************Connected To iNet Sprinta2000 Type - 4 Driver
String url="jdbc:inetdae7:servername:1433"; String login="userid"; String password="password"; Class.forName("com.inet.tds.TdsDriver"); System.out.println(" Connected To iNet Sprinta2000 Type - 4 Driver"); con=DriverManager.getConnection(url,login,password);
// ******************************Connected To iNet Opta2000 Type - 4 Driver String url="jdbc:inetdae7:servername:1433"; String login="sagar"; String password="sagar"; Class.forName("com.inet.tds.TdsDriver").newInstance(); System.out.println(" Connected To iNet Opta2000 Type - 4 Driver"); con=DriverManager.getConnection(url,login,password);
출처 : http://blog.empas.com/yooncom77/18149708
(출처 : BoKi - http://boki.tistory.com/9)

메일 에러 코드(SMTP 응답코드표)

** SMTP 응답코드표
211 : 시스템 상태 또는 시스템 도움말 답장
214 : 도움말 메시지 220 : 도메인 서비스가 준비됨
221 : 도메인 서비스가 전송 채널을 폐쇄하고 있음
250 : 요청된 우편행위 OK, 완료되었음
251 : 사용자가 Local이 아님 < 전진경로>로 배달
354 : 우편입력을 시작함 : .로 종료됨
421 : 도메인 서비스가 수행되지 않음, 전송 채널을 폐쇄하고 있음
451 : 요청된 행위가 강제 종료되었음 : 처리중 오류 발생
452 : 요청된 행위가 이루어지지 않았음 : 시스템 저장 장치가 충분하지 않음
500 : 구문오류, 명령이 인식되지 않음
501 : 매개변수나 인수에서 구문오류
502 : 명령이 구현되지 않았음 503 : 명령들의 순서가 잘못되었음
504 : 명령 매개변수가 구현되지 않았음
550 : 요청된 행위가 이루어지지 않았음 : 우편함이 이용될 수 없음
551 : 사용자가 로컬이 아님
552 : 요청된 우편 행위가 강제 종료됨 : 저장 장치 할당을 초과
553 : 요청된 행위가 이루어지지 않았음 : 우편함 이름 사용 불가
554 : 거래가 실패하였음




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




SERVER REPLY: 501 Denied domain name
도메인주소를 잘못 입력했거나 수신측에서 발송된 도메인을 수신거부한 경우입니다. 수신자의 도메인을 다시 확인하세요.


421 Server too busy.
수신측 서버의 응답이 지연된 경우입니다. 수신서버의 트래픽 부하 등으로 메일을 수신 하지 못하는 상황이면 발송자에게 이러한 리턴 메일을 보냅니다. 이런 메시지를 받으면 잠시 후 다시 편지를 발송해 보세요.


421-Microsoft ESMTP MAIL Service, Version: 5.0.2195.5600 ready at Service not available, closing transmission channel
MS사의 smtp 서버의 장애로 인해 메일을 수신받지 못하는 상황에서 리턴된 메시지입니다. 잠시 후 다시 발송해 보세요.


421 4.3.2 Your IP(218.236.***.***) is filtered and this connection will be closed. You must register your IP to spammaster@***.com.
***.com 서버로 메일 발송시 필터링 조건에 위배되어 스패머로 인식되고 필터링 되어 발송자에게 리턴되는 메시지입니다. 파란메일에서 보낸 메일에 대해 이러한 리턴메시지를 받은 경우 고객센터로 리턴메일을 첨부하여 신고하여 주십시오.


441 4.4.1 No answer from host
수신측 서버의 응답이 없어서 리턴된 경우입니다. 수신측 서버 담당자에게 문의하시면 조치가 가능합니다.


451 4.4.0 DNS resolving error
수신측 서버의 도메인을 못찾아 리턴된 메시지입니다. 수신측 서버 담당자에게 문의하시면 조치가 가능합니다.


451 4.3.0 Temporary system failure. Please try again later.
수신 서버의 일시적인 장애로 인해 메일을 수신받지 못해 리턴된 메시지입니다. 잠시 기다린후 다시 보내세요.


451 4.4.2 Bad connection (io timeout)
수신 서버의 응답이 없어서 응답시간이 초과 되어 발송자 메시지입니다. 수신측 서버의 장애일 가능성이 높으므로 수신측 서버 담당자에게 문의하세요.


451 Relay Server Not Ready.
수신측 서버에서 릴레이 기능이 안돼어 리턴된 메시지입니다.


452 4.4.5 Insufficient disk space; try again later
수신서버의 디스크용량이 부족하여 메일을 수신받지 못해 리턴된 메시지입니다. 수신측 서버 담당자에게 문의하시면 조치가 가능합니다.


452 4.4.5 <
test@sample.com>... Insufficient disk space; try again later
수신자(
test@sample.com)의 메일함 용량이 부족하여 편지를 수신하지 못하는 경우입니다. 수신자에게 알려주세요.


501 5.1.8 Sender domain must exist(honorstech.com)
수신측 도메인(honorstech.com)이 존재하지 않아 리턴된 메시지입니다. 수신측 서버 담당자에게 문의하시면 조치가 가능합니다.


505 Authentication required
수신측 서버가 릴레이 인증 등을 허용하지 않아 리턴된 메시지입니다. 하이텔, 한미르, 파란 SMTP 서버로 메일을 발송한 경우라면 서버속성 “보내는 메일 서버”의 인증필요를 꼭 체크해 주세요.


512 5.1.2 Bad destination system address
수신 서버의 장애나 네트웍 트래픽등으로 인헤 수신서버가 응답이 없을 때 리턴된 메시지입니다. 수신측 서버 담당자에게 문의하시면 조치가 가능합니다.


550 5.1.1 Suspended user <***@lycos.co.kr>
수신자의 메일 계정은 있으나 이용이 중단된 상태입니다. 일반적으로 수신사의 휴면정책에 의해 수신이 중지된 상태로 볼 수 있습니다.


550 5.1.2 <***@yahoo.net>... Unsupported mail destination
수신 서버가 응답이 지연되어 리턴된 메시지입니다. 수신측이 장애이거나 네트웍이 불안한 경우이니 잠시 후 다시 보내세요.


550 5.7.1 <***@chollian.net>... Access denied.(211.202.13.144) <***@chollian.net>
수신자(***@chollian.net)가 발송자의 메일주소를 수신 거부한 상태입니다.


550 Requested action not taken: mailbox unavailable
550 RCPT <
hghwe@kornet.net> ERROR. Mailbox doesn't exist
수신자의 메일함을 찾지 못하거나 존재하지 않아 리턴된 메시지입니다. 수신자의 서비스사로 문의하세요.


550 Mail is reject ( filtering reject )
수신 서버에서 발송자의 메일 주소나 IP를 필터링하여 거부되어 리턴된 메시지입니다. 발송사와 수신사에 모두 알려주시면 보다 빨리 해결될 수 있습니다.


550 5.1.1 <***@jeill.co.kr>... User unknown
550 Invalid recipient ***@fernand.com
수신자(***@µ돋事?를 찾지 못해 리턴된 메시지입니다. 수신자의 서비스사로 문의하세요.


553 5.3.0 <***@hananet.net>... spam
발송자의 계정이 수신서버 상에서 스패머로 등록이 되어 메일 수신을 거부해서 리턴된 메시지입니다. 수신사로 문의하세요.


553 sorry, your envelope sender is in my badmailfrom list
발송자의 메일 주소가 수신서버상에서 블랙리스트에 올라 거부된 상태입니다. 수신사로 문의하세요.


553 sorry, that domain isn't in my list of allowed rcpt hosts
발송자의 메일 도메인주소 자체가 수신 서버에서 차단되어 리턴된 메시지입니다. 발송사와 수신사에 모두 알려주시면 보다 빨리 해결될 수 있습니다.


553 5.1.8 <
uni@honorstech.com>... Domain of sender address uni@honorstech.com does not exist
발송자의 도메인에 대해 수신서버에서 체크 하여 없는 도메인일 경우 리턴시킨 메시지입니다. 발송사와 수신사에 모두 알려주시면 보다 빨리 해결될 수 있습니다.


553 5.0.0 We do not accept mail from spammers - If you have questions,please email
admin@www.narun.net.
553 sorry, your envelope sender is enlisted as spammer.

발송자의 메일 계정이 스패머로 수신서버에서 등록이 되어 리턴된 메시지입니다. 수신사로 문의하세요.


553 5.0.0 Your message may contain the Win32.Klez worm!!- If you have questions,please email
postmaster@ecweb-1.blueweb.co.kr.
발송자의 메일에서 Win32.Klez 라는 웜바이러스가 발견되어 리턴된 메시지입니다. 바이러스를 검사하세요.


553-This target address is not our MX service
수신자의 주소가 수신 서비스사에서 제공하지 않는 도메인일 경우 반송되는 메시지입니다. 수신자의 메일주소가 정확한지 확인하세요.


554 5.3.2 Rejected by mailbox host. REPLY:(250 <
ahnmin@thinknet.or.kr>... Sender ok)
수신자가 발송자의 메일 계정에 대해 수신 거부를 하여 리턴된 메시지중 하나입니다. 국내는 수신 거부를 하더라도 메시지를 반송하지 않는 경우가 대부분입니다. 반송할 경우 유효한 메일주소로 판단하여 스팸메일을 받게될 확률이 더욱 높아지기 때문입니다.


554 5.3.0 Mail have traversed Too many hops. Reject it.
발송자가 메일을 보낼 때 동보메일로 수신자의 메일 계정을 수신서버의 제한량 이상 넣어 보내어 리턴된 메시지.


2007년 5월 23일 수요일

MySQL-Standard-5.0.18 설치 방법

설치1.MySQL 설치.

1) cd /tmp

2) wget http://dev.mysql.com/get/Downloads/MySQL-5.0/mysql-standard-5.0.18-linux-i686-glibc23.tar.gz/from/http://mysql.byungsoo.net/

2) tar xvfz mysql-standard-5.0.18-linux-i686-glibc23.tar.gz

3) mv mysql-standard-5.0.18-linux-i686-glibc23 /usr/local/mysql

주의) /usr/local/mysql 폴더가 존재하는지 확인하고 있으면 반드시 지울것!

4) cd /usr/local/mysql

5) ./scripts/mysql_install_db

주의) 반드시 /usr/local/mysql 폴더에서 명령을 내릴 것! /usr/local/mysql/scripts로 들어가서 하지 마셈!

6) groupadd mysql

7) useradd -g mysql mysql

8) chown -R root /usr/local/mysql

9) chown -R mysql /usr/local/mysql/data

10) chgrp -R mysql /usr/local/mysql

11) chown -R root /usr/local/mysql/bin

12) ./bin/safe_mysqld --user=mysql &

주의)

[root@a1 mysql]# ./bin/safe_mysqld --user=mysql &
[1] 5948
[root@a1 mysql]#Starting mysqld daemon with databases from /usr/local/mysql/data (ENTER)

ENTER키를 치면 다시 프롬프트가 나타남

13) ps -ef | grep mysql

14) ./bin/mysqladmin -u root password "123456"

15) ./bin/mysql -p mysql

ssh로 폴더를 다른 서버로 복사하기

ssh namineya@xxx.xxx.xxx.xxx tar -c -O /tgplog/2006/ tar -xv

SVN 사용방법

co(=checkout) : svn co "http://sun.xxxxx.co.kr/xxxxxx/trunk"아무것도 없는 상태에서 원본 파일들을 가지고 오는 명령어
ci(=commit) : svn ci -m "수정내용 설명" 파일명파일을 수정한 후 설명 내용을 적어 서버에 적용 시키는 명령어
add(=add) : svn add 파일명새로운 파일을 생성했을시에 적용을 한후에 ci를 적어 주도록 하자.
up(=update) : svn up 파일명 혹시 변경 되었을지 모르는 소스를 변경 시켜주는 명령어
commit을 할경우에는 라인을 적게 해서 수정할것

Apache 서버 폴더리스트가 출력 안되게 할때

웹주소를 쓰구 특정폴더명을 쓰구 엔터친경우 파일목록 리스트가 출력되는 경우가 있다.
별로 안보여주고 싶은데 파일리스트가 주르륵 나올때 막아주는 방법

우선 httpd.conf 파일을 vi편집기로 연다.
/ 를 누르고 FollowSymLinks 를 검색해보자!!
그러면 딱 여기에 요게 보인다.
Options Includes Indexes FollowSymLinks
여기서 indexes 부분을 싸악 지워주고 저장한다.
그리고 아파치 재시작!!!

(가상호스트인경우는 각자 저 indexes가 써있는 경우가 있다.열씨미 찾아서 고쳐서 재부팅했는데도 안나와서 알고보니 가상호스트쪽에 하나 더 저 indexes가 있더군...고것도 고치고서 다시
아파치 재부팅하니까 제대로 작동됨)

2007년 5월 17일 목요일

진정한 웹2.0으로서의 UCC가 되려면

한동안 달랑 2컷으로 된 만화들이 날 즐겁게 하였는데 그것도 매번 똑같은 그림으로 된 것들이다. 알 만한 사람은 다 아는 이른바 ‘조삼모사 시리즈’이다.



원래 조삼모사(朝三暮四)는 춘추전국시대 송나라에 살던 저공이라는 사람의 이야기에서 유래한다. 저공은 자신이 기르던 원숭이에게 줄 도토리가 부족해지자 아침에는 3개, 저녁에는 4개로 줄이겠다고 원숭이들에게 통보하였다. 원숭이들이 이에 격렬히 항의하자 저공은 다시 아침엔 4개, 저녁엔 3개로 바꿔 제안을 하였다. 결국 똑 같은 말인데도 원숭이들은 나중 제안을 기뻐하며 받아 들였다는 것으로 사물의 본질을 보지 못하는 어리석음을 비유한 이야기이다.



여기서 저공과 원숭이의 대화 장면을 차용한 조삼모사 시리즈는, 저공이 뭐라 하자 난리를 치던 원숭이들이 그가 돌아서며 던진 한마디 말에 바로 불리함을 깨닫고 아부를 하는 모습을 재미있게 묘사한다. 특이한 것은 네티즌들에 의하여 대화 내용이 매번 바뀌면서 상황은 똑같지만 내용이 다른 촌철살인의 유머들이 쏟아져 나왔다는 점이다. 하도 많은 버전들이 만들어 져서 처음 나왔던 원본이 무엇인지도 모르게 되었지만, 서로들 만들어 낸 버전을 감상하며 공감하고 즐거움을 느꼈던 건 디지털 세상이 만들어 준 자그마한 행복이었다.



UCC, 과거를 부활시키다

이른 바 웹2.0 시대의 인터넷의 화두는 단연코 UCC(User Created Cotents) 또는 UGP(User Generated Contents)라 불리는 ‘이용자에 의하여 생산된 콘텐츠’이다.



다들 새로운 엘도라도를 발견한 듯이 UCC로 어떻게 수익을 올릴지 몰두하고 있고 구글에 거액에 인수된 유튜브의 사례는 UCC의 위력을 보여주는 신화가 된 것처럼 보인다. 어떻게 보면 대동강 팔아먹은 봉이 김선달보다 더 심한 것이 아닌가 하는 생각도 들지만 웹2.0의 지향점이 참여의 아키텍처에 의한 이용자들 자신의 개인적이고 이기적인 활동의 부산물로서 구축된 DB를 이용한 비즈니스이니 잘못된 방향은 아니다.



그러나 참여와 개방, 공유를 본질로 하는 웹2.0과 관련해서 UCC를 논하려면 단순히 ‘이용자에 의하여 생산된 콘텐츠’라는 정의만으로는 부족하다. UCC는 콘텐츠를 만든 자가 누구냐가 핵심이 아니라 콘텐츠에 누구나 접근 가능하고, 이를 누구나 가져갈 수 있으며, 제일 중요한 것은 그것으로 누구나 새로운 것을 만들 수 있다는 것이 본질이기 때문이다. 조삼모사 시리즈가 가능했던 바로 그 부분이다.



사실 이러한 의미에서의 UCC는 새로운 개념이 결코 아니다. 오히려 UCC는 창작의 원래 모습이다. ‘창작자’라는 계층이 따로 존재하지 않았던 과거로 돌아가 보자. 낮에 있었던 사냥을 떠올리며 동굴 벽에 그림을 그린 자나 여기에 자기 이야기를 덧붙인 자 모두 그 날 그 날 살아가느라 바빴던 평범한 사람들이다. 이 사람 저 사람이 흥얼거리던 노래는 어느덧 아리랑이라는 명곡이 되었으며 지역에 따라 다르게 바뀌어 새로운 버전이 만들어졌다. 눈먼 아버지를 위해 바다에 몸을 던진 어린 소녀의 부활이야기는 유교와 불교의 정신세계가 혼합되어 있는 것을 보더라도 어느 한사람의 창작이 아닌 오랜 세월동안 많은 이들의 손을 거쳐 완성된 스토리임이 틀림없다.



창작의 원래 모습이 UCC일 수밖에 없었던 것은 그 당시에는 창작행위가 돈벌이 수단이 아니라 단순히 즐기거나 자신의 생각, 감정을 표현하는 수단이었기 때문이다. 따라서 그 결과물인 창작물에 대한 독점이라는 개념이 없었다. 그러나 문화가 축적되어 저작물의 수준이 높아지고 새로운 전문가들이 두각을 나타내기 시작하면서 이야기는 달라진다.



천부적인 소질과 전문화된 실력을 갖춘 창작자들이 등장하고 그들이 만들어낸 창작물들이 높은 평가를 받고 그 가치가 인정되면서 이를 저장할 미디어와 널리 전파시키기 위한 네트워크가 고안되었다. 미디어와 네트워크의 발달은 창작물의 온전한 보존과 공간적 범위의 확장을 가져오면서 전문 창작자의 지위와 창작물의 경제적 가치를 더욱 더 높였고 이는 다시 창작행위를 그와 같은 전문가들에게 집중되게 만들었다. 점차 문화적 수준에서 뒤지고 경제적, 시간적 여유가 부족한 일반인들은 일방적인 수용자로 전락하게 되었다. 이러한 상황의 변화는 저작물에 대한 저작자의 독점적 이익을 강화하고 그의 허락 없이는 아무도 손을 댈 수 없는 원칙을 만들어 냈다. 저작권법이 등장하고 점차 강력한 저작권의 모습을 갖춰간 것이 이 무렵이다.



그러나 20세기 후반에 나타난 기술의 발전은 역설적으로 과거의 부활을 가져왔다. 고비용의 미디어에 의존하지 않고도 창작물을 무형적인 디지털 정보 자체로서 저장, 인식할 수 있게 되고 인터넷이라는 비용 제로의 혁명적인 배포수단이 등장하면서 일반인들이 넘볼 수 없었던 미디어와 네트워크의 장벽이 무너졌다. 또한 창작을 위한 기술적, 경제적 어려움이 극복되면서 이전에는 엄두도 내지 못했던 높은 수준과 대규모의 저작물을 쉽게 만들어 낼 수 있게 되었다. 무엇보다도 중요한 점은 커뮤니케이션수단의 발달과 정보검색의 진전으로 창작을 위한 온갖 정보가 확산되면서 일반인들의 문화적 수준이 높아졌다는 점이다. 진정한 UCC의 부활이 가능해진 셈이다.



UCC, 저작권법 장벽과 마주치다

그러나 부활은 부활인데 완벽하지 않다는 것이 문제이다. UCC는 부활하였지만 그때 당시에는 존재하지 않았던 저작권법이라는 장벽을 마주치게 된 것이다.



저작권법은 원본인 저작물을 변형하는 행위를 두 가지로 나누어 규정하고 있다. 변형한 결과 새로운 창작성이 더해져서 사회통념상 원저작물과는 다른 독자적인 저작물이 된 경우 이를 ‘2차적저작물’이라 한다. 이와는 달리 그 창작성의 정도가 낮아 수정, 가감이 이루어진 것에 불과한 경우는 저작물의 단순한 ‘변경’에 해당한다. 즉 원저작물에 가미된 창작성의 수준에 따라 구별되는데, 변형물이 2차적저작물로 인정되면 원저작물과는 독립하여 새로운 저작물로서 보호를 받게 된다는 점이 단순한 변경의 경우와 제일 큰 차이점이다.



저작권법은 저작권자에게 위 두 경우를 모두 컨트롤 할 수 있는 배타적 권리를 부여하고 있다. 원저작자의 허락을 받지 않고 2차적 저작물을 만들면 저작재산권인 ‘이차적저작물작성권’을 침해한 것으로, 허락 없이 원저작물을 변경한 경우는 저작인격권인 ‘동일성유지권’을 침해한 것이 된다. 위에서 언급한 것처럼 2차적저작물이 새로운 저작물로서 보호받게 된다고 하더라도 원저작자의 허락을 안 받았다면 그의 이차적저작물작성권을 침해한 사실은 변함이 없다.



물론 저작권이 전문창작자만을 위한 것은 아니다. 창작자를 차별함이 없이 자신의 저작물에 대한 권리는 모두에게 동등하게 주어진다. 문제는 그 유래를 보더라도 알 수 있듯이 저작권법이라는 시스템은 UCC가 아닌 전문창작자의 경제적, 독점적 권리를 보호하기에 적합한 시스템이라는 점이다. 만인에게 동등하게 적용되는 저작권법의 원칙은 오히려 UCC의 부활을 방해하는 부작용을 낳고 있는 셈이다.



자연스로운 콘텐츠 순환과정을 만들어야

게다가 대부분의 UCC 플랫폼들이 UCC의 본질을 실현할 수 있는 여건을 만들지 못하고 있는 것이 사정을 더욱 악화시키고 있다.



UCC 플랫폼들이 가지고 있는 상당수의 UCC가 출발부터 진정한 UCC가 아닌 사이비 UCC(User Copied Contents)라는 점도 문제지만 그나마 이용자가 만들어낸 콘텐츠로서의 UCC임에도 이마저 제대로 구현되지 못하고 있는 것이 현실이다. 대부분의 UCC 플랫폼들이 집중하고 있는 것은 UCC의 확보, 확보된 UCC로부터의 수익, 그리고 창작자와의 수익분배이다. 물론 중요한 사항이다. 그러나 콘텐츠를 확보하여 수익을 내고 이를 창작자와 나눠 가진다는 개념은 그 콘텐츠가 아마추어에 의한 것이든 프로에 의한 것이든 큰 의미는 없다. 그걸 굳이 웹2.0이라고 부를만한 혁신적인 것이라 할 수 있겠는가. 스크랩 기능을 더하여 자유롭게 스크랩해 갈 수 있는 여건을 마련한다고 하더라도 크게 사정이 달라지는 것도 아니다.



진정한 웹2.0로서의 UCC를 추구한다면 원래의 모습대로 누구나 접근가능하고 누구나 가져갈 수 있으며 누구나 변형시킬 수 있는 콘텐츠의 장을 마련하여 참여와 개방과 공유를 실현시켜야 한다. 즉 UCC에 적합하지 않은 저작권을 해결할 수 있도록 플랫폼 자체에서 지원을 해 주어야 한다. 정체불명의 개념인 스크랩 허용만 달랑 달아놓을게 아니라 콘텐츠의 개방과 공유를 계몽, 유도하면서 CCL이나 정보공유라이선스처럼 자신의 저작물을 남들이 어떻게 이용할 수 있는지, 새로운 2차적저작물의 작성을 허용할 것인지 나타내 줄 수 있는 간편한 방법을 마련해 주어야 한다. 기술적인 면에서도 수정, 변환이 어려운 포맷으로 UCC를 보관할 것이 아니라 좀 더 유연하고 다양한 포맷을 지원하여 제3자에 의한 접근과 수정이 가능하도록 배려할 필요가 있다.



그래서 웹2.0에서 추구하는 콘텐츠의 순환과정이 자연스럽게 이루어지게 하여야 한다. UCC 제공자에게 정당한 수익을 나누어 주는 것도 좋지만, 그게 전부는 아니다. 어느 누구는 단지 자유롭게 즐길 수 있는 놀이터와 친구들이 생겼다는 것만으로 만족할 것이기 때문이다. 오히려 그것이 UCC 플랫폼이 우선적으로 접근해야 할 기본적인 방향이고, 더욱더 수준 높은 제2, 제3의 조삼모사 시리즈를 만들어 낼 수 있는 환경이다.@

출처 : ZDNet Korea <윤종수(서울 북부지원 판사) >

UCC 현황과 전망 [1]

사용자의 자발적 반응이 시작되었다.



네모, 파이, 플레이, TV팟, 야미, 붐, 큐… 올해 포털 사이트에서 신규 런칭된 UCC 콘텐츠 들이다. UCC는 그만큼 강력한 화두였고, 선두 포털 사이트들은 다양한 이름의 서비스들을 경쟁적으로 만들어 냈다. 그리고 위의 서비스들처럼 동영상 또는 이미지 중심의 서비스들 외에도 블로그와 같은 텍스트 중심의 UCC도 계속 업그레이드 되고 있다.



이런 실물적인 서비스가 나오고 있음에도 불구하고, UCC는 웹2.0이라는 단어와 함께 일종의 마케팅 유행어로 취급되고 있기도 하다. 비즈니스 트랜드에 뒤떨어진 사람들의 푸념이라고 볼 수도 있지만, 몇 가지 부분에서 거슬리는 부분이 있는 것도 사실이다.



무엇보다 소비자와 합의되지 않은 영문 이니셜을 이용한 개념어가 구체적인 서비스에 앞서 먼저 사용되었다는 것이 그렇고 – 일반 소비자들은 UCC를 모를 수도 있다. – ‘일반 사용자에 의해 생산되는 콘텐츠’라는 것은 이미 웹 초창기에 ‘웹’ 스스로를 칭찬했던 대표적 멘트 중 하나였기 때문이다.



하지만 이런 회의론자들에게 보란 듯이 UCC는 이미 상당한 양의 방문자들을 확보했으며 아래 그림과 같이 방문자들이 늘어나는 경향을 보이고 있다.



포털 UCC 주요 사이트 방문자수 추이


용어는 다소 겉멋 들었고 이미 익숙한 개념인 것은 사실이지만, 사용자들은 충실히 반응하고 있다는 얘기다.



사실 일부 회사에서 퍼뜨린 마케팅 유행어라는 혐의를 떨치지 못하면서도,UCC의 매력을 떨치지 못하고 있는 이유가 여기에 있다. 인터넷은 사용자의 자발성을 근거로 시작했으며, 이들의 자발성을 높이는 방향으로 진화하고 있기 때문이다.



유통 채널로써 기능 확장

1998년에 함께 영화 평론을 공부하던 친구들과 웹진을 공동으로 발행한 적이 있었다. 그다지 유명하지는 않았지만, 아마추어 글쟁이들 치고는 나름대로 주목 받았던 것으로 기억한다. 지금으로 치면 UCC라는 이름을 붙여주기에 알맞은 콘텐츠가 아니었나 싶다.



어쨌든 각자의 생계 활동에도 불구하고 처음 1년간은 매월 꾸준히 업데이트를 진행했지만, 그 후 1년간 정기 업데이트 일정을 거의 지키질 못했고 결국 2년을 채 못 채우고 폐간을 선택할 수밖에 없었다.



그 당시 안타까웠던 것은 두 가지다. 하나는 힘들여 생산한 글들에 대한 제대로 된 유통 채널이 있으면 좋겠다는 것이고, 또 하나는 그 일을 통해서 생계를 유지할 수 있으면 좋겠다는 것이었다.



현재의 UCC 서비스의 양태를 보면 전자는 해결된 듯 싶다. 블로그는 적어도 검색 포털 내에서는 매우 평등한 매체이다. 그리고, 트랙백과 같은 기능은 댓글 자체도 콘텐츠 유통에 포함시켜 생산된 글에 대한 토론 행위를 인터넷 공간에서 무한히 확장한다.



이것은 분명히 최초 인터넷 산업 시기에 우리가 보지 못했던 부분이다. 콘텐츠의 생산이 아닌 생산된 콘텐츠의 평등한 유통과 유통 라인의 무한한 확장. 이는 그야말로 UCC를 위한 새로운 인프라라고 할 수 있다.



현재는 크게 활성화되어 있지 않을 지라도 이 기술적 인프라는 향후 UCC의 활성화에 큰 기여를 할 것으로 예상된다. @

출처 : ZDNet Korea <랭키닷컴 송정훈 컨설팅사업부장>

2007년 5월 9일 수요일

MS, 어도비 플래시에 도전장

MS는 어도비시스템즈가 자랑하는 플래시 플레이어에 대적할만한 새로운 제품을 출시했다.

공식 이름은 「실버라이트(Silverlight)」. 실버라이트는 플래시 플레이어와 마찬가지로 웹상에 동영상을 제공하는 미디어 및 엔터테인먼트 회사들을 주 타깃으로 하고 있다.
소비자로서는 다양한 제품으로 인하여 선택의 폭이 넓어지고 그에 따라서 질적인 향상을 가져온다면 좋을 일일 수도 있겠지만 개발자 입장에서는 달갑지 않은 일일 수도 있을 듯 싶다. 더욱이 그 대상이 MS라는 것,

새로운 기술을 바탕으로 기존의 툴로 불가능 했던 것을 만들어 낸다던가, 기존의 제품보다 향상된 퍼포먼스를 자랑한다면 좋은 현상이겠지만 그런 것이 아닌 비슷한 제품으로 서로 힘의 논리로 시장을 형성해 간다면 좋은 일은 아닐 것이다.

가만히 보면 MS라는 회사는 미국이라는 나라의 애국주의와 많은 부분 닮아있다는 생각도 든다. 물론 자본주의 사회에서의 시장원리를 무시할 수는 없는 일이지만 그로 인해서 피해를 보고 더 발전적인 방향으로 가지 못한 부분들도 많은 것 같다.


MS는 9일(미국시간) 라스베이거스에서 개최되고 있는 NAB(National Association of Broadcasters) 쇼에서 실버라이트를 공식 출시한다.

실버라이트는 미디어 파일을 재생하고 여러 운영체제에 유연성 있게 웹 애플리케이션을 제공하는 웹 브라우저 기능 확장용 소프트웨어이다.

MS 측은 과거에 「WPF/E (Windows Presentation Foundation/Everywhere)」라고 불렸던 실버라이트의 베타 버전을 다음 달 디자이너들과 웹 개발자들이 참여할 Mix07 컨퍼런스에서 선보일 예정이다.

실버라이트의 공식 출시와 함께 MS는 실버라이트를 사용하는 것에 관심을 보인 몇몇 미디어와 광고 에이전시 파트너들을 소개하는 자리를 마련할 계획이다.

이런 파트너들에는 현재 MLB(미 프로야구), 온라인 동영상 방송회사인 브라이트코브, 그리고 넷플릭스와 아카마이 테크놀로지스 등이 있다.

2년여의 개발과정을 거친 실버라이트는 인터넷 익스플로러, 파이어폭스, 또는 사파리 등, 윈도우와 맥에서 웹 애플리케이션을 제공할 수 있는 소프트웨어이다. 플레이어의 용량이 2메가바이트 이하인 것 또한 하나의 장점이다.

플래시처럼 실버라이트 또한 디자이너와 소프트웨어 개발자 둘 모두를 위한 개발 툴을 가지고 있다.

NAB 컨퍼런스를 통해 실버라이트를 출시함으로써 MS는 현재 온라인상에서 활약하고 있는 미디어 회사들의 관심을 유발하기 위해 노력하고 있다. MS의 윈도우 미디어 플레이어 포맷은 다운로드 된 동영상을 재생하는 데 널리 사용된다.

하지만 마이스페이스닷컴이나 유튜브 등과 같은 인기 사이트에서 실시간으로 동영상을 재생하는 데에서는 어도비의 플래시 플레이어가 가장 많이 사용되는 것이 사실이다.

한 예로, 브라이트코브의 마케팅 및 전략 부문 부회장 아담 베리(Adam Berrey)는 그들이 서비스하는 모든 동영상을 현재 플래시를 통해 제공하고 있다. 하지만 브라이트코브는 올해 말부터 실버라이트를 사용하기 시작해 소비자들의 관심을 끌어 모을 예정이라고 밝혔다.

베리는 "실버라이트의 장점은 바로 윈도우 미디어 비디오(Windows Media Video)의 포맷을 브라우저상에서 매우 일관성 있게 구현하기 때문"이라며 "우리가 지금까지 윈도우 미디어 비디오를 지원하지 않았던 이유는 사용자를 배려하는 그런 서비스를 제공하지 못하고 있었다고 판단해서"라고 설명했다.

하지만 그는 브라이트코브가 앞으로도 어도비 플래시와 「플렉스(Flex)」 개발 툴들을 이용해 콘텐츠 보유자들이 브라이트코브 서비스로 동영상을 업로드 할 수 있도록 제작된 툴을 포함한 추가 소프트웨어를 제작할 예정이라고 밝혔다.

어도비, MS라는 장애물 직면
웹 동영상의 급속한 확산과 더불어 어도비와 MS 간의 경쟁은 더욱 심화될 것으로 보인다.

MS는 이미 미디어 사업 부문에 상당한 고객을 보유하고 있고, 이들 중 상당수는 온라인 콘텐츠 부문을 확장하는 것을 고려중인 것으로 알려져 있다.

또한 MS는 그들의 제품에 대한 고정 고객층인 소프트웨어 프로그래머들을 보유하는 것을 넘어서 그래픽과 웹 디자이너들 또한 새로운 고정 고객층으로 유치하기 위해 노력하고 있다. 어도비의 제품 수익 중 절반은 창조적인 전문가들을 위한 제품으로부터 나오고 있다.

이에 대비해서 어도비는 콘텐츠 오서링(authoring)을 통해 웹 개발 부문과 연계하고자 하고 있다.

이에 대한 노력의 일환으로 어도비는 최근 디자이너들이 사진, 동영상 등과 같은 콘텐츠를 지면상 혹은 웹이나 모바일 기기 등을 통해 제공할 수 있도록 도와주는 「크리에이티브 스위트 3(Creative Suite 3)」를 소개한 바 있다.


사용자 삽입 이미지






































제공: Microsoft

MS가 NAB 쇼를 통해 웹상에서 미디어를 재생하고 다양한 웹 애플리케이션 상에서 사용이 가능한 새로운 웹 브라우저 플러그 인 실버라이트를 소개할 것이라고 밝혔다. 또한 MS는 WPF/E라는 코드 명으로 불렸던 이 제품에 관심을 보인 퍼블리셔 및 광고 에이전시 파트너들을 소개하는 자리를 마련할 예정이다.

한편 어도비 또한 NAB 쇼를 통해 「필로(Philo)」라는 코드 명으로 알려진 「어도비 미디어 플레이어(Adobe Media Player)」를 선보일 예정이다.

이는 플래시 포맷의 동영상을 오프라인 상에서 재생할 수 있도록 만들어진 무료 소프트웨어다. 올해 말에는 사용자들이 직접 비디오 「팟캐스트(Podcast)」에 대한 RSS 피드를 선택하고 또 운영할 수 있게 하는 어도비 미디어 플레이어를 출시할 예정이다.

MS 서버 및 툴 부문 생산 운영을 담당하고 있는 포레스트 키(Forest Key)는 실버라이트가 플래시보다 더 앞선 성능을 보일 것이라고 주장했다.

그는 실버라이트가 벡터 그래픽(vector graphics)을 사용하기 때문에, 브라우저 페이지 상에서 재생되는 동영상의 창을 마음대로 조정할 수 있다고 강조했다. 또한 MS는 콘텐츠 제작자들을 위한 디지털 저작권 운영 툴을 제공할 예정이라고 밝혔다.

이와 더불어 윈도우나 웹 애플리케이션을 사용하는데 있어 MS의 닷넷(.Net) 툴에 익숙한 개발자들은 온라인 동영상과 관련해서도 그들이 보유하고 있는 기술들을 그대로 사용할 수 있다.

MS는 2분기 말경에, 그래픽 디자이너들과 웹 개발자들을 타깃으로 한「익스프레션 스위트(Expression suite)」툴을 출시할 예정이다.

MS는 또한 NAB 쇼를 통해 현존하는 윈도우 미디어 비디오 파일을 웹상에서 재생할 수 있도록 하는 툴인 익스프레션 미디어 인코더(Expression Media Encoder)를 소개할 예정이다.

실버라이트의 유저 인터페이스 디자인은 MS가 자체 개발한 XAML 이라는 언어를 통해 제작됐다.

애플리케이션은 이 밖에도 자바스크립트나 HTML을 통해서도 제작될 수 있다. Mix07에서 MS는 실버라이트 애플리케이션을 제작하는데 사용할 수 있는 기타 여러 세부적인 프로그램 언어들에 대해서도 설명할 예정이라고 키는 말했다.

결과적으로 MS는 모바일 기기에서 실행될 수 있는 실버라이트 버전을 제작하는 것을 목표로 하고 있다.

MS가 실버라이트를 사용할 여러 파트너들을 섭외 했음에도 불구하고, 아직까지 광범위한 산업계의 지원은 받지 못하고 있는 상태이다.

호스트 애플리케이션 제공 업체인 세일스포스닷컴(Saleforce.com)의 제품 마케팅 담당자 아담 그로스(Adam Gross)는 "아직 실버라이트가 시장의 주류가 아니기 때문에" 실버라이트를 사용할 계획이 없다고 밝혔다.

또한 MS는 NAB 컨퍼런스를 통해 동영상을 더욱 효율적으로 운영할 수 있도록 개선될 윈도우 롱혼 서버에 관한 계획에 대해서도 소개할 예정이라고 밝혔다.

롱혼 서버에 대한 개선 작업은 올해 말경에 완료될 예정이다. 이와 더불어 미디어 및 엔터테인먼트 산업에 최적화된 셰어포인트 서버(SharePoint server)와 관련한 부분에 논의 할 예정이다.

출처 : Martin LaMonica ( CNET News.com )

2007년 4월 13일 금요일

Apache 웹 서버 장애 해결하기 7 (검색 로봇의 접근 차단하기)

검색 로봇의 접근 차단하기

갑자기 특정한 IP 주소에서 짧은 시간에 많은 접속을 하여 시스템의 부하가 올라가 웹 접속 로그를 살펴보니 다음과 같이 이해할 수 없는 내용이 남는 경우 가 있다.
211.51.63.4 - - [26/Sep/2001:22:19:42 +0900] "GET /robots.txt HTTP/1.0" 404 285
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /index.asp HTTP/1.0" 404 284
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /index.php HTTP/1.0" 404 284
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /index.php3 HTTP/1.0" 404 285
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /default.htm HTTP/1.0" 404 286
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /default.html HTTP/1.0" 404 287
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /default.asp HTTP/1.0" 404 286
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /default.php HTTP/1.0" 404 286
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /default.php3 HTTP/1.0" 404 287
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /main.htm HTTP/1.0" 404 283
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /main.html HTTP/1.0" 404 284
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /main.asp HTTP/1.0" 404 283
211.51.63.4 - - [26/Sep/2001:22:19:44 +0900] "GET /main.php HTTP/1.0" 404 283
211.51.63.4 - - [26/Sep/2001:22:19:44 +0900] "GET /main.php3 HTTP/1.0" 404 284
무작위로 index.php, index.asp, index.php3, default.html, default.asp 등 의 파일을 순서대로 요청하는 것으로 보아 검색 엔진일 가능성이 높다고 가정 할 수 있다. 특히 robots.txt 파일을 요청하는 것으로 검색 엔진이라고 장담 할 수 있을 것이다.
httpd.conf에서 Logformat를 common 대신 {User-agent} 변수를 추가하여 정의 하면 서버에 접근하는 에이전트 정보도 알 수 있는데, UA(User Agent)는 일반 적인 웹브라우저 뿐만 아니라 검색 로봇이나 방랑 로봇 등 웹 서버에 접속하여 웹페이지를 가져오거나 해석하는 모든 종류의 프로그램을 뜻한다. 이는 흔히 사용하는 익스플로러나 넷스케이프 등의 브라우저 외에도 라이코스의 스파이더(spider)나 알타비스타의 스쿠터(Scooter)와 같은 검색 로봇과 텔리포트(Teleport)나 WebZIP, GetRight 등 오프라인 브라우저 모두 UA의 범위에 속한다. 검색 로봇이 어떤 사이트를 방문하여 문서를 인덱싱하거나 오프라 인 브라우저가 페이지를 한꺼번에 요청하여 긁어 가는 것은 일반 사용자가 웹 브라우저로 서버에 접속하여 원하는 페이지를 보는 일반적인 경우와 그 성격 이 다르다. 여러 페이지를 동시에 요청하는 정도를 벗어나 아예 한 웹사이트 의 모든 페이지를 짧은 시간에 통째로 긁어가기도 하기 때문에 이러한 경우에 는 서버에 매우 많은 프로세스를 생성하면서 웹 서버의 로드가 크게 올라가게 되는 것이다. 특히 DB와 연동하는 사이트의 경우에는 심할 경우 정상적인 서비스를 하지 못 할 정도이다.
모든 사이트가 검색 엔진에 등록될 필요는 없거나 또는 허용된 일부 유저만 접근이 가능한 페이지의 경우 로봇의 접근을 차단할 필요가 있으므로 이러한 경 우에는 다음과 같이 설정된 robots.txt 파일을 웹 서버의 최상위 / 디렉토리 에 두면 모든 검색 로봇이 /secure 디렉토리를 인덱싱하지 않는다.
User-agent: *
Disallow: /secure
User-agent: *”는 모든 로봇를 대상으로 한다는 것을 뜻하며 예를 들어 알타비스타 스쿠터 등 특정한 UA에 대해서만 설정하고 싶다면 다음과 같이 하면 된다.
User-agent: scooter
검색 로봇과 관련된 더 자세한 정보를 얻기 원한다면 다음의 사이트를 참고하 기 바란다.
http://info.webcrawler.com/mak/projects/robots/robots.html
http://info.webcrawler.com/mak/projects/robots/norobots.html
아울러 웹 서버에서 특정한 유저 에이전트의 접근을 차단하려면 httpd.conf에 다음과 같이 BrowserMatch를 사용하여 설정해도 된다.
BrowserMatch "WebZIP" go_out
BrowserMatch "Teleport" go_out
BrowserMatch "GetRight" go_out
BrowserMatch "WebCopier" go_out
BrowserMatch "NetZip Downloader 1.0" go_out
BrowserMatch "NetZip-Downloader/1.0.62" go_out
BrowserMatch "Teleport Pro/1.29" go_out
BrowserMatch "Teleport Pro/1.24" go_out
BrowserMatch "Teleport Pro/1.26" go_out

Options Includes ExecCGI
AllowOverride None
Order allow,deny
Allow from all
Deny from env=go_out

위와 같이 설정 시에는 /home/no-ua/ 디렉토리 이하에 대해서는 go_out이라는 변수에 지정한 WebZip이나 Teleport 등 UA 프로그램의 접근을 차단하게 된다. 다른 UA도 차단하고 싶으면 위와 같이 웹 서버의 로그를 살펴보아 에이전트 정 보에 남는 UA를 go_out으로 추가해 주면 된다. 같은 방식으로 만약 특정 디렉토리 이하에 대해서 MSIE 브라우저로 접근하지 못하도록 설정하려면 다음과 같 이 BrowserMacth를 이용한다. 이렇게 하면 에이전트 정보에 MSIE라 설정되는 UA는 차단될 것이다.
BrowserMatch "MSIE" msie

Options Includes ExecCGI
AllowOverride None
Order allow,deny
Allow from all
Deny from env=msie
최근에는 각종 로봇이 버전을 새롭게 하며 계속적으로 나오고 있으므로 지속적으로 로그를 살펴보아 접근 통제를 하고자 하는 UA를 설정하는 것이 좋다.

Apache 웹 서버 장애 해결하기 6 (특정한 이름의 파일을 실행을 제한하려면 )

특정한 이름의 파일을 실행을 제한하려면
최근에는 대부분의 사이트들이 대화방(채팅)을 위해 자바로 프로그래밍된 자바 대화방을 사용하는 추세이지만 얼마 전까지만 하더라도 C나 펄로 된 CGI 대 화방을 설치하여 사용하는 것이 유행이었다. 그런데 이 대화방의 경우 대화방 에 참여하는 유저 중 한 명이 글을 입력할 경우 모든 유저에게 이 내용이 실시 간으로 나타나야 하는 특성상 시스템의 메모리를 매우 많이 소모하는 대표적 인 프로그램 중 하나였다.
따라서 채팅 CGI 프로그램을 원천적으로 사용할 수 없도록 하는 방법을 고민하게 되었는데, 해결 방법은 대부분의 채팅 프로그램이 xxxchat.cgi 또는 chatxxx.cgi라는 파일을 실행 파일 이름으로 한다는 특징을 이용하면 된다. 즉, httpd.conf를 열어 다음과 같이 설정하면 파일명에 ‘chat’이라는 단어 가 포함된 CGI 파일은 작동하지 않게 되는 것이다.

Order allow,deny
Deny from all
이러한 방식으로 특정한 파일에 대해 웹에서의 접근을 차단할 수 있다. 따라 서 CGI 파일에 아무리 소유권과 실행 권한을 주었다 하더라도 웹 서버 자체에 서 접근을 거부하였으므로 웹에서 접근하면 Forbidden’에러가 나게 된다. 이러한 식으로 특정 파일 이름을 가진 파일의 실행이나 접근을 차단할 수 있다

Apache 웹 서버 장애 해결하기 5 (용량 큰 파일의 업/다운로드시 부하가 유발될 경우 )

누구나 업/다운로드가 가능한 자료실을 운영하고 있을 경우 사이즈가 너무 큰 파일을 업/다운로드 할 경우 부하가 많이 걸리게 되어 결국 시스템의 성능 저 하를 유발하게 된다. 최근 배포되는 게시판/자료실 프로그램에서는 대부분 업로드할 수 있는 용량 등을 제한할 수 있는 기능이 있지만 그렇지 않은 프로그램도 상당수 있어 웹 서버 차원에서 이 제한을 적절히 설정할 필요가 있다. 아파치에서는 이와 관련하여 웹 서버에서 업/다운로드 할 수 있는 파일의 사이즈를 제한하는 Limit RequestBody 기능을 이용할 수 있다.
LimitRequestBody는 클라이언트가 요청시 http 프로토콜을 통해 서버가 제공 할 수 있는 메시지의 크기를 바이트 단위로 정의하는 것으로 무한대를 의미하는 0부터 2,147,483,647(2Giga)까지 설정 가능하며 이 설정으로 대용량의 파일 을 업/다운로드 하는 형태의 서비스 거부 공격을 차단할 수 있다. 이를 설정하는 방법은 httpd.conf를 열어 다음과 같은 라인을 추가하면 된다.

LimitRequestBody 7168000


LimitRequestBody 10240000
위와 같이 LimitRequestBody 인자를 설정하면 아파치 웹 서버를 이용하여 업/ 다운로드 하는 모든 파일의 사이즈를 7MB로 제한하고 /home/special/ 이하에 대해서는 10MB로 제한하게 된다. 위와 같이 설정시 지정된 사이즈를 초과하는 파일을 업/다운로드 시에는 다음 그림과 같은 에러 메시지가 뜨며 업/다운 로드가 되지 않는다.

Apache 웹 서버 장애 해결하기 4 (프로세스가 과도한 메모리를 사용할 경우)

프로세스가 과도한 메모리를 사용할 경우
특별히 이상한 프로세스는 없는데, 시스템의 부하가 갑자기 올라가는 경우가 있다. 심할 경우에는 콘솔에서 키 작동이 되지 않아 제어 자체가 불가능한 경 우도 있는데, 이러한 경우는 어쩔 수 없이 시스템을 재 시작하는 수밖에 없다. 이는 의도적이든 아니든 유저가 cgi나 php 등의 프로그램을 잘못 짜서 과도한 메모리를 소모하는 프로세스를 실행하기 때문인 경우인데, 실제로 시스템의 메 모리를 많이 소모하는 프로그램을 짜는 것은 단 몇 줄의 코드로도 가능하다. 다음과 같이 메모리를 소모하는 간단한 C 코드를 작성해 보자(참고로 스크립트 키드의 악용을 막기 위해 코드 중 일부를 변경하였다).
/* memory.c */

#include
#include

void html_content(void);

int main() {
char *some_memory;
int size_to_allocate = ONE_K;
int megs_obtained = 0;
int ks_obtained = 0;

html_content();
printf("Program Executed !!!

");

while (1) {
for (ks_obtained = 0; ks_obtained < 1024; ks_obtained++) {
some_memory = (char *)malloc(size_to_allocate);
if (some_memory == NULL) exit(EXIT_FAILURE);
sprintf(some_memory, "Hello World");
}
printf("Now allocated %d Megabytes
n", megs_obtained);
}
exit(0);
}

void html_content(void)
{
printf("Content-type: text/htmlnn");
}
작성 후 gcc -o memory.cgi memory.c로 컴파일 한 후 이 파일을 http://domain.com/memory.cgi와 같이 웹에서 실행해 보도록 하자. 아무리 메 모리와 CPU의 여유가 있는 시스템이라 하더라도 이 프로그램을 실행하자마자 거의 통제 불능 상태로 되어 결국 시스템 재부팅하게 될 것이다. 이렇듯이 메 모리를 무한정 소모하는 것을 차단하기 위해서는 아파치의 설정 인자 (Directive) 중에서 RLimitMEM을 사용하여 차단할 수 있다. 이 인자는 아파치 웹 서버에서 생성된 특정 프로세스가 작동시 소요 가능한 최대 메모리의 양을 제한하는 것으로 메모리를 많이 소모하는 CGI가 작동할 때 이 인자에서 지정 된 메모리까지만 실행이 되고 그 이상 소요시에는 더 이상 작동하지 않도록 해 준다.
예를 들어 httpd.conf에 다음과 같이 설정하였다면 모든 디렉토리에서는 메모 리를 20MB나 최대 21MB까지만 사용이 가능하고 /home /special/public_html/* 디렉토리 이하에 접근 시에는 특별히 50MB까지 메모리 이용이 가능하게 된다.
RLimitMEM 20480000 21504000


RLimitMEM 51200000 52224000
실제로 위와 같이 설정 후 memory.cgi를 웹에서 호출하면 아래와 같이 일정량 의 메모리만 사용되고 중단하는 것을 확인할 수 있다. 이와 비슷한 인자로 CPU 점유율을 제한하는 RLimitCPU와 사용자당 프로세스의 개수를 제한할 수 있는 RLimitNPROC이 있다. 이에 대해서는 http://httpd.apache.org/docs-2.0/mod/core.html를 참고하기 바란다.

Apache 웹 서버 장애 해결하기 3 (include를 잘못하여 무한 루프가 돌 경우)

include를 잘못하여 무한 루프가 돌 경우
요즘에는 php와 mysql을 연동하여 많이 사용하고 있는데, 프로그래밍 과정에서 의 실수로 php 파일에서 같은 php 파일을 include하는 경우가 있다. 또는 a.php 파일에서 b.php 파일을 include하고 b.php 파일에서 다시 a.php 파일을 include하는 경우도 그러한 경우일 것이다. 이러한 경우에는 무한 루프가 돌 게 되어 결국은 아파치 데몬이 금새 Maxclients에서 지정한 개수로 차 버리게 되는데, 어떤 파일에서 무한 루프가 돌고 있는지 찾기가 힘들다. 따라서 임시로 다음과 같이 include를 하지 못하도록 차단을 하는 방법이 있다.
# iptables -A INPUT -p tcp -i lo -s xxx.xxx.xxx.xxx --sport 1024:65535 -j DROP
이는 같이 서버 내에서 include 시에는 lo(Lookback Interface)를 통해 sport 가 1024 이후의 하이 포트를 이용하여 통신한다는 특성을 이용한 것이다. 그러 나 이 설정을 하였을 경우 로컬 서버에서 클라이언트 포트를 전혀 사용할 수 없게 되므로 다른 서비스에도 장애가 되기 때문에 임시로만 사용하기 바란다. 또는 ps aux grep http로 보이는 프로세스에서 ls -la/proc /pid/로 각각의 http 프로세스가 어떤 파일을 참조하고 있는지 일일이 추적하는 방법도 있다.(예:cwd -> /home/user1/public_html/infinite_loop/)

2007년 3월 21일 수요일

Apache 웹 서버 장애 해결하기 2 (서비스 거부 공격(DoS)이 가해졌을 때)

서비스 거부 공격(DoS)이 가해졌을 때
DoS는 동시에 서비스할 수 있는 프로세스의 한계가 있다는 점을 악용한 공격이다.
한번의 실행으로 100개나 200개 등 원하는 만큼의 동시 접속을 맺은 후 이 접속을 끊지 않고 유지할 수 있는 공격 코드가 인터넷 상에 공개되어 있다.
그러나 이러한 공격의 경우 공격지의 IP를 속이기가 매우 어려우므로 netstat으로 확인 후 비정상적인 접속으로 확인 될 경우 해당 IP를 차단하면 된다.
특정 IP의 라우팅을 차단하는 방법은 다음과 같이 route를 이용한 방법과 iptables(커널 2.4 이상)를 이용한 방법 두 가지가 있다.

Apache 웹 서버 장애 해결하기 1 (접속이 느려지거나 접속이 안 될 때)

접속이 느려지거나 접속이 안 될 때
가끔 접속자가 많은 서버를 운영하다 보면 갑자기 웹 접속이 되지 않거나 접속 이 너무 느려 아파치 데몬 개수를 확인해 보면 httpd가 256개나 떠 있는 경우 가 있다.
기본적으로 아파치 웹 서버의 경우 Max Clients가 256으로 설정되어 있어 동시에 256개의 데몬이 뜨게 되면 더 이상의 접속을 받아들이지 않고, 기 존의 프로세스가 죽을 때까지 대기한 후 접속이 끊기게 되면 그제서야 접속을 받아들이게 된다.
따라서 동시 접속이 많은 경우에는 이전의 웹 접속이 끊길 때까지 대기해야 하 므로 접속 속도가 느린 것처럼 느끼게 되는 것이다.
일반적으로 정상적인 접속 의 경우에 256개의 프로세스가 모두 뜨는 경우는 그리 많지 않기에 현재의 상 태가 비정상적인 접속인지 여부를 판단해야 한다. 이를 판단할 수 있는 방법 은 netstat -na grep ES로 ESTA BLISHED된 연결 상태를 확인하여 클라이언트 의 IP가 정상적인 연결인지 여부를 확인하면 된다.
또는 netstat -nagrep ESawk '{print $5}'sort로 클라이언트의 IP만 따로 소트하여 확인해 봐도 된다. 통상적으로 HTTP 1.1 규약에서부터 적용되기 시작 한 KeepAlive 기능을 지정하였을 경우 한 클라이언트 IP에서 동시에 3~5개 정 도의 http 프로세스를 생성하므로 한 IP에서 3~5개 정도의 프로세스를 생성하는 것은 정상적인 현상이다.
비정상적인 접속의 경우에는 다음과 같은 이유가 있을 수 있다.

Apache의 access_log에 관련된 파일형식 남기지 않게 하는 방법

이미지 서버를 구축해 사용하다 보면 access_log에 여러가지 파일형식의 로그들이 쌓여서
용량이 초과하는 경우가 많았을것이다. 여기서 로그들을 주석처리해서 막아 버리는 방법도
있지만 아래와 같이 해서 부분적으로 로그 쌓임을 방지 할수가 있다.

Apache httpd.conf 파일을 열어 다음의 내용들을 추가 하도록 하자.

### JPG Red Deny ####
SetEnvIf Request_URI \.jpg worm
SetEnvIf Referer \.jpg worm

### GIF Red Deny ####
SetEnvIf Request_URI \.gif worm
SetEnvIf Referer \.gif worm

### SWF Red Deny ####
SetEnvIf Request_URI \.swf worm
SetEnvIf Referer \.swf worm

### html Red Deny ####
SetEnvIf Request_URI \.html worm
SetEnvIf Referer \.html worm

### CodeRed Deny ####
SetEnvIf Request_URI \.ida worm
SetEnvIf Referer \.ida worm

### Nimda Deny #####
SetEnvIf Request_URI cmd\.exe worm
SetEnvIf Referer cmd\.exe worm
SetEnvIf Request_URI root\.exe worm
SetEnvIf Referer root\.exe worm
SetEnvIf Request_URI admin\.dll worm
SetEnvIf Referer admin\.dll worm

CustomLog /usr/local/apache/logs/access_log common env=!worm

진한 부분이 CustomLog 부분에 추가해줘야 할 부분이다.

Apache log들 용량을 줄이고 싶을때 사용하는 명령어

아파치 로그를 확인 하다보면 엄청난 양의 access_log,error_log를 확인할때가 있을것이다.
이때 이 양을 0으로 만드는 방법을 소개 하겠다.

cat /dev/null > access_log
cat /dev/null > error_log

Apache 버젼 확인 방법

부끄럽지만 내가 일하면서 알게 된 명령어ㅋㅋ
/usr/local/apache/bin/httpd -v
끝~~

Apache 웹서버에서 폴더 리스트가 출력 안되게 할려면...

Apache를 이용해 웹서버를 구축후에 이런 문의를 받았다
"폴더 리스트가 나오는데 안나오게 할 수 없나요"
이 문의를 받고 난 열심히 웹서핑을 시작하였다.

찾아낸 정보는 다음과 같다.

Apache 설정 파일인 httpd.conf 파일을 열고
/를 키워드 검색을 하자. 찾을 단어는 'FollowSymLinks'
찾게 되면 다음과 같은 문구를 볼수 있다.
Options Includes Indexes FollowSymLinks

그럼 여기서 어떻게 하면 되느냐 indexes를 지워주도록 한다.
그리고 Apache Restart를 해준후에 접근을 해보자. 그럼 원하던대로...

p.s 가상호스트일 경우에는 가상호스트 설정부분에도 indexes를 삭제해주면 된다.

2007년 3월 10일 토요일

linux서버에서 python으로 mysql 사용하는 cgi쉽게 만들기

집필자 : shinmoosung 님이 쓰신 글입니다. 좋은 자료가 될꺼 같아 가지고 왔습니다.


먼저 리눅스 서버를 설치하고,
1. apache 2.0.x이상
2. python최신버전
3. mysql 최신버전
4. MySQLdb(mysql.org의 download에 보면, python 연결용 connector들을 제공한다)

각각의 프로그램의 설치는 이곳에서 설명을 생략한다.

단, apache의 httpd.conf에서는 AddHandler cgi-script .cgi를 설정하는 것과 cgi가 실행될
디렉토리에서 Options +ExecCGI 를 해주어야 cgi가 실행되므로 잊지 않고 설정한다.

이제 python의 라이브러가가 설치된 디렉토리로 간다.
python2.4.x버전에 설치되었다면 보통 /usr/lib/python2.4 폴더가 된다.

이곳에서 dp.py파일을 만들고

import _mysql
class usedb:
def __init__(self,MyDB='test'):
self.db = _mysql.connect(user='mysql',db=MyDB)
def __del__(self):
conn.close()
def query(self, SQLstr=''):
if SQLstr == '':
return "Nothing to execute"
self.db.query(SQLstr)
return self.db.store_result().fetch_row(0)

의 내용을 입력하고 저장한다. 그리고 파일권한은 644로 해둔다.
위의 내용에서 볼 수 있는 것처럼 mysql에는 기본적으로 test데이터 베이스가 있으므로, 데이터베이스를 지정하지 않았을 때는 자동적으로 그것을 사용하게 하였다.

user는 mysql계정으로 사용한다. 이것은 최근의 mysql버전의 설치에서 기본적으로 만들게 되는 계정이므로 그대로 사용한다.

이제 cgi를 실행하도록 된 디렉토리로 가서 아래의 내용으로

test.cgi를 만든다.
#!/usr/bin/python
print "Content-Type: text/html\n"
from db import usedb

s = "show tables;"
d = usedb('information_schema')
print d.query(s)

d = usedb()
print d.query(s)

파일을 저장하고 권하는 755로 한다.

그리고 웹에서 접속해 보면 test.cgi는 python을 이용하여, mysql의 데이터베이스를 사용하는 것을 볼 수 있다.
information_schema는 최신 mysql에서 기본적으로 제공하는 데이터베이스이다.
usedb() 처럼 데이터 베이스를 지정하지 않은 경우 자동적으로 test데이터베이스를 사용한다. SQL문법에 대한 설명은 생략한다.

이상으로 linux의 apache서버에서 python을 사용하여 cgi를 작성한 후, mysql데이터 베이스를 사용할 수 있는 방법을 설명하였다.

이상의 내용은 본인이 밤을 새워가면서, 외국의 자료들을 찾아가면서 얻은 값진 지식입니다. 국내에서는 이러한 지식을 보지 못했네요. 아직까지는요. MySQLdb를 써도 좋기는 합니다.
앞의 내용이 잘못된 부분이 있어서 코드를 완전히 수정해서 다시 올립니다. 신고
shinmoosung (2006-04-10 14:04)출처 : [직접 서술] 앞의 내용처럼 본인이 직접 코딩한 것입니다. 다른 분들이 발전시켜도 좋습니다.

앞의 내용은 제가 약간 이해를 못한 부분이 있어서 약간의 문제를 포함하고 있었음을 사과드립니다.
아래의 내용은 완전히 테스트를 통해 확인한 내용입니다.

먼저 클래스를 정의한 db.py의 내용을 아래처럼 수정합니다.

--------------------------------------------------------------------------------
import _mysql

class usedb:
def __init__(self, MyDB='test'):
self.DBname=MyDB
def do(self, SQLstr=''):
if SQLstr == '':
return "Nothing to do"
self.db=_mysql.connect(db=self.DBname,user='root')
self.db.query(SQLstr)
self.result=self.db.store_result().fetch_row(0)
self.db.close()
return self.result



--------------------------------------------------------------------------------

user='root' 부분은 각자의 mysql설정에 따라서 실행이 가능한 계정이면 됩니다.
즉, user='mysql'일 수도 있고, mysql설정에 따라서 아주 생략해도 되기도 합니다.
이제는 cgi가 실행되는 디렉토리에 test.cgi를 생성해서 다음의 내용을 입력합니다.

--------------------------------------------------------------------------------

#!/usr/bin/python
print "content-type:text/html\n"



from db import *
import cgitb; cgitb.enable()


d = usedb('mysql')
s= d.do("show tables;")
print s
print "

"

d = usedb('information_schema')
print d.do('show tables;')
--------------------------------------------------------------------------------

import cgitb; cgitb.enable()은 코드 디버깅을 위한 것이므로, 디버깅이 끝나면 삭제합니다.
이 예제 cgi에서는 mysql데이터베이스와 information_schema데이터베이스의 테이블목록을 보여주는 단순한 쿼리를 실행합니다.

일단 이것이 성공하면, 다른 SQL쿼리들도 된다는 이야기이지요.

웹에서 http://서버/test.cgi 로 실행합니다.

(리눅스)linux apache에서 python을 사용해서 mysql사용하기 신고
shinmoosung (2006-04-10 15:24)출처 : [직접 서술] 제가 직접!!! 연구하고 작성한 코드들입니다. 부족한 부분은 다른 사람들이 고쳐서 쓰세요. 이로써 리눅스의 아파치 서버에서 파이썬(python)으로 mysql데이터베이스 프로그래밍이 아주~~ 쉽게 가능해졌네요... php, jsp, asp 모두 물렀거라! 가장 쉬운 파이썬 나가신다~

앞에서 작성된 db.py 클래스 코드에 데이터베이스를 생성하는 createdb 메서드와 dropdb 메서드를 추가하여 완성한 코드를 올립니다.


db.py

--------------------------------------------------------------------------------
import _mysql

class usedb:

def __init__(self, MyDB='test'):
self.DBname=MyDB

def do(self, SQLstr=''):
if SQLstr == '':
return "Nothing to do"
self.db=_mysql.connect(db=self.DBname,user='root')
self.db.query(SQLstr)
self.result=self.db.store_result().fetch_row(0)
self.db.close()
return self.result

def createdb(self, MyDB):

"""db이름이 지정되지 않았으면 오류"""
if MyDB == '':
return "Specify the Database name to be created."

self.db=_mysql.connect(db='test',user='root')

"""같은 이름의 db가 있으면 오류"""
self.db.query("show databases;")
self.result=self.db.store_result().fetch_row(0)
for i in self.result:
if i[0] == MyDB:
self.db.close()
return "Database already exits!"

"""db 생성 및 결과 반환"""
self.db.query("create database " + MyDB + ";")
self.db.query("show databases;")
self.result=self.db.store_result().fetch_row(0)
for i in self.result:
if i[0] == MyDB:
return "Database successfully created!"
self.db.close()

def dropdb(self, MyDB):

"""db이름이 지정되지 않았으면 오류"""
if MyDB == '':
return "Specify the Database name to drop."

self.db=_mysql.connect(db='test',user='root')

"""삭제할 db가 있으면 삭제 실행"""
self.db.query("show databases;")
self.result=self.db.store_result().fetch_row(0)
for i in self.result:
if i[0] == MyDB:
self.db.query("drop database " + MyDB + ";")
self.db.close()
return "Database successfully droped!"
self.db.close()
return "Specified database not exits!"



--------------------------------------------------------------------------------

자세한 사용설명은 위의 내용을 참고하시고,
실제 사용 코드는 다음과 같습니다.

--------------------------------------------------------------------------------
#!/usr/bin/python
print "content-type:text/html\n"

from db import *
import cgitb; cgitb.enable()

#데이터 베이스 생성

d = usedb()
s = d.createdb("mydb")
print s
print "

" # -->그냥 줄넘기기 *^^*


#데이터 베이스 삭제
s = d.dropdb("mydb")
print s
print "

"
--------------------------------------------------------------------------------

출처 : [직접 서술] 이상의 내용은 본인이 밤을 새워가면서, 외국의 자료들을 찾아가면서 얻은 값진 지식입니다. 국내에서는 이러한 지식을 보지 못했네요. 아직까지는요. MySQLdb를 써도 좋기는 합니다.

Comparing Python to Other Languages(Python과 다른 언어와의 비교)

Disclaimer: This essay was written sometime in 1997. It shows its age. It is retained here merely as a historical artifact. --Guido van Rossum

Python is often compared to other interpreted languages such as Java, JavaScript, Perl, Tcl, or Smalltalk. Comparisons to C++, Common Lisp and Scheme can also be enlightening. In this section I will briefly compare Python to each of these languages. These comparisons concentrate on language issues only. In practice, the choice of a programming language is often dictated by other real-world constraints such as cost, availability, training, and prior investment, or even emotional attachment. Since these aspects are highly variable, it seems a waste of time to consider them much for this comparison.

Java
Python programs are generally expected to run slower than Java programs, but they also take much less time to develop. Python programs are typically 3-5 times shorter than equivalent Java programs. This difference can be attributed to Python's built-in high-level data types and its dynamic typing. For example, a Python programmer wastes no time declaring the types of arguments or variables, and Python's powerful polymorphic list and dictionary types, for which rich syntactic support is built straight into the language, find a use in almost every Python program. Because of the run-time typing, Python's run time must work harder than Java's. For example, when evaluating the expression a+b, it must first inspect the objects a and b to find out their type, which is not known at compile time. It then invokes the appropriate addition operation, which may be an overloaded user-defined method. Java, on the other hand, can perform an efficient integer or floating point addition, but requires variable declarations for a and b, and does not allow overloading of the + operator for instances of user-defined classes.

For these reasons, Python is much better suited as a "glue" language, while Java is better characterized as a low-level implementation language. In fact, the two together make an excellent combination. Components can be developed in Java and combined to form applications in Python; Python can also be used to prototype components until their design can be "hardened" in a Java implementation. To support this type of development, a Python implementation written in Java is under development, which allows calling Python code from Java and vice versa. In this implementation, Python source code is translated to Java bytecode (with help from a run-time library to support Python's dynamic semantics).

Javascript
Python's "object-based" subset is roughly equivalent to JavaScript. Like JavaScript (and unlike Java), Python supports a programming style that uses simple functions and variables without engaging in class definitions. However, for JavaScript, that's all there is. Python, on the other hand, supports writing much larger programs and better code reuse through a true object-oriented programming style, where classes and inheritance play an important role.

Perl
Python and Perl come from a similar background (Unix scripting, which both have long outgrown), and sport many similar features, but have a different philosophy. Perl emphasizes support for common application-oriented tasks, e.g. by having built-in regular expressions, file scanning and report generating features. Python emphasizes support for common programming methodologies such as data structure design and object-oriented programming, and encourages programmers to write readable (and thus maintainable) code by providing an elegant but not overly cryptic notation. As a consequence, Python comes close to Perl but rarely beats it in its original application domain; however Python has an applicability well beyond Perl's niche.

Tcl
Like Python, Tcl is usable as an application extension language, as well as a stand-alone programming language. However, Tcl, which traditionally stores all data as strings, is weak on data structures, and executes typical code much slower than Python. Tcl also lacks features needed for writing large programs, such as modular namespaces. Thus, while a "typical" large application using Tcl usually contains Tcl extensions written in C or C++ that are specific to that application, an equivalent Python application can often be written in "pure Python". Of course, pure Python development is much quicker than having to write and debug a C or C++ component. It has been said that Tcl's one redeeming quality is the Tk toolkit. Python has adopted an interface to Tk as its standard GUI component library.

Tcl 8.0 addresses the speed issuse by providing a bytecode compiler with limited data type support, and adds namespaces. However, it is still a much more cumbersome programming language.

Smalltalk
Perhaps the biggest difference between Python and Smalltalk is Python's more "mainstream" syntax, which gives it a leg up on programmer training. Like Smalltalk, Python has dynamic typing and binding, and everything in Python is an object. However, Python distinguishes built-in object types from user-defined classes, and currently doesn't allow inheritance from built-in types. Smalltalk's standard library of collection data types is more refined, while Python's library has more facilities for dealing with Internet and WWW realities such as email, HTML and FTP.

Python has a different philosophy regarding the development environment and distribution of code. Where Smalltalk traditionally has a monolithic "system image" which comprises both the environment and the user's program, Python stores both standard modules and user modules in individual files which can easily be rearranged or distributed outside the system. One consequence is that there is more than one option for attaching a Graphical User Interface (GUI) to a Python program, since the GUI is not built into the system.

C++
Almost everything said for Java also applies for C++, just more so: where Python code is typically 3-5 times shorter than equivalent Java code, it is often 5-10 times shorter than equivalent C++ code! Anecdotal evidence suggests that one Python programmer can finish in two months what two C++ programmers can't complete in a year. Python shines as a glue language, used to combine components written in C++.

Common Lisp and Scheme
These languages are close to Python in their dynamic semantics, but so different in their approach to syntax that a comparison becomes almost a religious argument: is Lisp's lack of syntax an advantage or a disadvantage? It should be noted that Python has introspective capabilities similar to those of Lisp, and Python programs can construct and execute program fragments on the fly. Usually, real-world properties are decisive: Common Lisp is big (in every sense), and the Scheme world is fragmented between many incompatible versions, where Python has a single, free, compact implementation.



--Guido van Rossum저. (이강성 역)

Java (자바)
Javascript (자바스크립트)
Perl (펄)
Tcl (티클)
Smalltalk (스몰톡)
C++
Common Lisp and Scheme


--------------------------------------------------------------------------------
Python은 흔히 Java, JavaScript, Perl, Tcl 또는 Samlltalk와 같은 인터프리터 언어와 비교된다. C++, Common Lisp 그리고 Scheme과 같은 비교되 부각된다. 이 절에서 난 이들 언어를 간단히 비교할 것이다. 이 비교는 언어적인 측면에서만 다룬다. 실제적으로, 프로그래밍 언어의 선택은 다른 실세계 제약(비용, 유용성, 학습 그리고 선행 투자비용 혹은 감성적인 친근감까지도)에 의해 자주 언급되기도 한다. 이러한 면들은 아주 가변적이고, 이러한 면으로 비교를 한다는 것은 시간 낭비에 가깝다.

Java (자바)
일반적으로 Python 프로그램은 Java 프로그램 보다는 느리게 수행된다. 하지만 Python 프로그램은 개발하는 시간이 훨씬 적게 걸린다. Python 프로그램은 Java 프로그램보다도 3-5배 정도 코드가 짧다. 이 차이는 Python의 내장 고수준 데이터 형과 동적인 형결정 기능에서 기인한다고 생각한다. 예를 들면, Python 프로그래머는 인수나 변수의 형을 선언하는데 시간을 허비하지 않고, 구문적인 지원이 언어안에 내장되어 있는 Python의 강력한 다형질의 리스트(polymorphic list)와 사전 형은 거의 모든 Python 프로그램에서 유용하게 활용되고 있다. 실행시간 형결정으로 인해서 Python의 실행시간에 Java가 하는 것보다 좀더 많은 일을 한다. 예를 들면, a+b와 같은 식을 계산할 때, 먼저 컴파일시에 알려지지 않은 a와 b 객체를 검사하여 그들의 형을 알아내야 한다. 그리고 나서 적절한 덧셈 연산을 호출한다. 그 덧셈 연산은 객체에 따라 사용자에 의해 오버로드(overloaded)된 것일 수 있다. 반면에, Java는 효과적인 정수형, 실수형 덧셈을 한다. 하지만 a와 b의 변수선언을 요구하고, + 연산자에 대한 사용자 정의 연산자 오버로딩을 허용하지 않는다.

이러한 이유들로, Python은 '접착' 언어로서 아주 적당한 반면, Java는 저수준 구현 언어로 특성화 지을 수 있다. 사실 이 두 언어는 아주 훌륭한 조합을 이룬다. Java에서 개발된 요소(components)들이 Python에서 활용된다; Python 역시 Java로 구현되기 전에 그 프로토타입을 정하는데 활용된다. 이러한 형의 개발을 지원하기 위해, Java로 쓰여진 Python 구현(implementation)이 개발중이다. 이것은 Java에서 Python을 호출하고 그 반대도 가능하게 해준다. 이 구현으로, Python 소스코드는 Java 바이트코드로 (Python의 동적 의미를 지원하기 위한 실행시간 라이브러리의 도움으로)번역된다.

Javascript (자바스크립트)
Python의 '객체기반' 부분 집합이 대략 JavaScript와 동일하다. JavaScript와 같이 (그러나 Java와는 다르게), Python은 클래스안에 정의하지 않아도 되는, 단순한 함수와 변수를 사용하는 프로그래밍 스타일을 지원한다. 하지만 JavaScript는 이것이 지원하는 전부이다. Python은, 반면에, 훨씬 큰 프로그램을 클래스와 상속이 중요한 역할을 하는 진정한 객체 지향 프로그래밍 스타일을 통하여 더 좋은 코드 재사용을 하도록 지원한다.

Perl (펄)
Python과 Perl은 비슷한 배경에서 개발되었다(유닉스 스크립트언어에서 성장했다). 그리고 많은 비슷한 기능을 지원한다. 그러나 철학은 다르다. Perl은 보편적인 응용지향 태스크를 지원하는데 중심을 두었지만 (예:내장 정규식 표현, 파일 스캐닝과 보고서 생성 기능들), Python은 보편적인 프로그래밍 방법론 (자료구조 설계 및 객체지향 프로그래밍)을 지원한다. 그리고 프로그래머가 우와하고(elegant) 암호같지 않은 코드를 통해 일기 쉽고 관리하기 쉽도록 한다. 결과적으로, Python이 Perl과 가깝지만 그 원래 응용 영역을 침범하는 일은 많지 않다. 하지만 Python은 Perl의 적합한 응용분야 외에 많은 부분에서 적용성을 갖는다.

Tcl (티클)
Python과 같이 Tcl은 독립적인 프로그래밍 언어 분 아니라, 응용 확장언어(extension language)로도 사용된다. 하지만, 전통적으로 모든 데이터를 문자열로 처리하는 Tcl은 자료구조에 약하고 Python 보다 실행에 시간이 많이 걸린다. Tcl은 또한 모듈러 이름영역(name space)와 같은, 큰 프로그램을 쓰기에 적합한 특징들을 가지고 있지 않다. 따라서 Tcl을 사용하는 전형적인 큰 응용 프로그램은 특별히 그 응용에 필요한 C나 C++로 확장된 부분을 갖는다. 이에 반해서 Python 응용 프로그램은 '순수한 Python'으로만 흔히 기술된다. 물론 순수한 Python을 이용한 개발은 C나 C++부분을 쓰고 디버깅하는 것보다도 훨씬 빠르다. Tcl의 결점을 매우는 부분이 Tk 툴킷이다. Python은 Tk을 표준 GUI 라이브러리로 쓰도록 적용했다.

Tcl 8.0은 바이트코드를 도입하여 빠른 처리를 했고, 제한된 데이터 형 지원과 이름영역을 지원한다고 하지만 여전히 거추장스러운 프로그래밍 언어이다.

Smalltalk (스몰톡)
아마도 Python과 Smalltalk의 가장큰 차이는 Python이 보다 더 '주류(mainstream)' 구문을 가진다는 것이다. Python은 Smalltalk과 같이 동적인 형결정과 결합(binding)을 한다. Python의 모든 것은 객체이다. 하지만, Python은 내장 객체 형과 사용자 정의 클래스를 구별하고, 내장 형으로부터의 상속은 현재로서 허용하지 않는다. Smalltalk의 데어터 타입의 표준 라이브러리 모음은 훨씬 섬세한 반면, Python의 라이브러리는 인터넷과 WWW 세계 (email, HTML, FTP등) 에 적응하기 좋은 많은 기능을 제공한다.

Python은 개발환경과 코드 배포에 있어서 다른 철학을 갖는다. Smalltalk이 환경과 사용자 프로그램을 포함하는 통일된 '시스템 이미지'를 갖는데 반해, Python은 표준 모듈과 사용자 모듈을 다른 파일에 저장하여 쉽게 재배열되고 시스템 밖으로 배포될 수 있다. 한 결과를 예를 들면, GUI가 시스템 안에서 설계된 것이 아니므로, GUI를 붙이기 위한 한가지 이상의 선택이 Python 프로그램에 있다.

C++
Java에 대해서 이야기 한 대부분이 C++에도 적용된다. Python코드가 Java 코드보다 3-5배 짧으며, C++코드에 비해 5-10배 짧다!! 일 예로 한명의 Python 프로그래머는 C++프로그래머 두 명이 1년에 끝낼 수 없는 일을 두달만에 끝낼 수 있다. Python은 C++로 쓰여진 코드를 사용하는 접착 언어로 빛을 발한다.

Common Lisp and Scheme
이들 언어는 동적인 의미해석에서 Python에 가깝다. 그러나 구문해석 접근은 너무 달라서 매우 심한 논쟁거리가 될 만한 비교가 된다: Lisp의 구문적인 부족함이 장점일까 단점일까? Python은 Lisp과 같은 내성적인 능력(capabilities)이 있고, Python 프로그램은 아주 쉽게 프로그램 부분을 구성해서 실행할 수 있다는 것을 밝혀야겠다. 일반적으로, 실세계 실체가 결정적이다: Common Lisp은 크다(어떠한 관점에서도 그렇다). Scheme 세계는 많은 어울리지 않는 버전들로 나누어져있다. 그에 반해서 Python은 하나이고, 무료이고, 작게 구현되었다. 더 자세한 Scheme와의 비교에 관해선 Moshe Zadka가 쓴 Python vs. Scheme을 보라.