1. 施罰勞馬(시벌로마)

 

고대 중국의 당나라 때 일이다.

한 나그네가 어느 더운 여름날 길을 가다 이상한 장면을 목격하였다.

한 농부가 밭에서 허벌나게 열심히 일하는 말의 뒤에 서서 자꾸만 가혹하게 채찍질을 가하는 광경을 본 것이다.

 

계속해서 지켜보던 나그네는 말에게 안쓰러운 마음이 들어 농부에게 "열심히 일하는 말에게 왜 자꾸만 채찍질을 하는가?"고 물었다.

 

그러자 그 농부는 자고로 말이란 쉬임없이 부려야 다른 생각을 먹지 않고 일만 열심히 하기 때문이라고 답했다.

 

남의 말을 놓고 가타부타 언급할 수가 없어 이내 자리를 뜬 나그네는 열심히 일하는 말이 불쌍하여 가던 길을 멈추고 뒤를 돌아보며 긴 장탄식과 함께 한마디를 내뱉었다 한다.

 

"! 施罰勞馬(시벌로마)"

 

훗날 이 말은 후세 사람들에게 이어져 주마가편(走馬加鞭)과 뉘앙스는 약간 다르지만 상당히 유사한 의미로 쓰였다 한다.

 

施罰勞馬(시벌로마) :

열심히 일하는 부하직원을 못잡아먹어 안달인 직장상사들에게 흔히 하는 말

 

- 한자공부 : :행할 시 罰:죄 벌 勞:일할 로 馬:말 마

:달릴 주 馬:말 마 加:더할 가 鞭:채찍 편

 

- 용법 :

아랫사람이 노는 꼴을 눈뜨고 보지 못하는 일부 몰상식한 상사의 뒤에 서서 들릴락 말락하게 읊어주면 효과적일 것이다.

 

, 이 말을 들은 상사의 반응에 대해서는 책임질 수 없다.

왜냐하면 아직 국내의 현실에 비추어 이 고사성어의 심오함을 깨달을 상사는 거의 없기 때문이다.....

 

2. 足家之馬(족가지마)

 

이 고사성어는 '분수에 지나친 행동을 경계하라'는 깊은 교훈을 담고있다.

 

아주 먼 옛날 중국 진나라시대에, 어느 마을이 있었는데 그 마을사람들의 성씨는 신체의 일부를 따르는 전통이 있었다.

대대로 귀가 큰 집안은 이(), 화술에 능통한 사람을 많이 배출한 집안은 구()씨와 같은 식이였다.

 

그곳에 수()씨 집안이 있었는데, 그 집안은 대대로 손재주가 뛰어난 집안이었다.

''씨 집안에는 매우 뛰어난 말 한 필이 있었는데, 이 역시 수씨 집안의 손재주에 의해 길들여진 것이었다.

 

어느 날 도적들과의 전쟁에 수씨집안의 큰 아들이 이 말을 타고나가 큰 공을 세워 진시황으로부터 벼슬을 받았다.

 

이것을 본 앞집의 족()씨 집안에서는,

"손재주나 우리 집안의 달리기를 잘하는 발재주나 비슷하니 우리도 말을 한 필 길러봄이 어떨까....?"

 

하여 말 한 필을 길들이기 시작했다. 한 달후, 도적들이 보복을 위해 마을로 내려왔다.

이를 본 족씨는 아들에게, "어서 빨리 수씨 집안보다 먼저 우리 말을 타고 나가거라."

 

하였고, 족씨 집안의 장자는 말을 타고 나가다 대문의 윗부분에 머리를 부딪혀 어이없게도 죽고 말았다. 이를 본 족씨는 통곡하며,

 

"내가 진작 분수에 맞는 행동을 했더라면, 오늘의 이 변을 막을 수 있었을 것을..."

하며 큰 아들의 주검을 붙잡고 통곡하였다.

 

이 때부터 세인들은 분수에 맞지않는 말이나 행동을 하는 사람에게 '足家之馬(족가지마)'라고 말하곤 한다.

 

足家之馬(족가지마) :

자기의 주제도 모르고 남의 일에 참견하거나 분수에 맞지않는 행동을 하는 사람에게 흔히 하는 말

 

파생어 :

足家苦忍耐(족가고인내) - 족씨가문의 큰아들이 분수를 몰라 죽음으로 인해 비롯된 고통임으로 누구에게 하소연도 못하고 참을수 밖에 없는 인내를 말한다)

 

3. 始發奴 無色旗(시발노 무색기)

 

옛날부터 중국 고사에는 삼황오제의 이야기가 전해진다.

그 중 복희씨는 주역의 만들었을 뿐 아니라, 길흉화복을 점치는 법을 만들었다고 전해진다.

이 이야기는 그 복희씨 시대의 이야기이다.

 

복희씨가 중국을 다스리고 있던 어느 날, 태백산의 한 산마을에 돌림병이 나서 많은 사람이 죽어가고 있다는 전갈을 들었다.

 

그리하여 복희씨는 그 마을로 향하게 되었는데, 그 마을은 황하의 물이 시작되는 곳이라 하여, 시발(始發) ()이라 불리고 있었다.

 

그 마을에 도착한 복희씨는 돌림병을 잠재우기 위해 3일 낮 3일 밤을 기도 하였는데, 3일째 되는 밤 기도 도중 홀연 일진광풍이 불면서 왠 성난 노인이 나타나

'나는 태백산의 자연신이다. 이 마을사람들은 몇 년째 곡식을 거두고도 자연에게 제사를 지내지 않으니, 이를 괘씸히 여겨 벌을 주는 것이다. 내 집집마다 피를 보기 전에는 돌아가지 않으리.' 하였다.

 

복희씨는 자연신이 화가 난 것을 위로하기 위해 방책을 세우고 마을 사람들을 불러모아 말하였다.

 

'자연신의 해를 피하기 위해선 집집마다 깃발에 동물의 피를 붉게 묻혀 걸어두어야 하오! '

 

그런데, 그 마을사람 중에 시발(始發)()의 관노(官奴)가 하나 있었으니, '귀신은 본디 깨끗함을 싫어하니, 나는 피를 묻히지 않고 걸 것이다.'하여 붉은 피를 묻히지 않은 깃발을 걸었다.

 

그날 밤 복희씨가 기도를 하는데, 자연신이 나타나 노여워하며 말하길

'이 마을사람들이 모두 정성을 보여 내 물러가려 하였거늘, 한 놈이 날 놀리려 하니 몹시 불경스럽도다. 내 역병을 물리지 않으리라.' 하였다.

 

그리하여 다음날부터 전염병이 더욱 돌아 마을 사람들이 더욱 고통스럽고 많은 이가 죽었으니, 이는 '그 마을(시발현)의 한 노비가 색깔 없는 깃발을 걸었기(始發奴 無色旗)' 때문이었다.

 

이 이야기로 인해, 그 이후 혼자 행동하여 다른 사람에게 피해를 입히는 사람이나, 제대로 알지도 못하면서 마구 행동하는 사람을 보면, ' 始發奴(시발노) 無色旗(무색기)'라고 하게 되었다.

 

오늘 익혀야 할 한자 :

(시작할 시) (발할 발) (노예 노) (없을 무) (색 색) (깃발 기)

 

 

 

4. 趙溫馬 亂色氣(조온마 난색기)

 

이 고사성어는 '사람들 틈에서 경거망동한 행동을 삼가라'는 깊은 교훈을 담고있다.

 

옛날 중국 춘추전국시대에 조씨성을 가진 사람이 살고 있었다.

조씨에게는 만삭인 부인이 있었는데, 어느날 아침 부인이 말하길,

 

"여보! 어제 밤 꿈에 말 한 마리가 온천으로 들어가 목욕을 하는 꿈을 꾸지 않았겠어요.

 

아마도 우리가 말처럼 활달하고 기운센 아들을 얻게 될 태몽인것 같아요." 라고 하였다. 조씨는 심히 기뻐하여,

 

"그것 참 좋은 태몽이구려 어서 빨리 우리 아들을 보았으면 좋겠소."

라고 하였다.

 

사흘 뒤 조씨부인은 매우 건강한 사내아이를 순산하였고, 조씨는 태몽을 따라 아이의 이름을 '溫馬(온마)'라 하였다.

 

세월이 흘러 조온마가 스무 살이 되었다.

조온마는 조씨부부의 기대와는 달리, 마을의 처녀란 처녀는 죄다 욕보이는 난봉꾼이 되었다.

 

이를 보다 못한 마을 사람들은 결국 조온마를 관아에 고발하였고 조온마는 판관앞에 끌려가게 되었다.

 

판관이 말하길,

"조온마는 색기로 인하여 마을을 어지럽혔다(趙溫馬亂色氣:조온마난색기). 따라서 거세를 당함이 마땅하다." 라고 하였다.

 

결국 조온마는 거세를 당하였고, 후일 사람들은 경거망동하는 사람에게 조온마의 일을 상기시키기 위하여 "조온마난색기"라고 충고를 하게 되었다고 한다.

 

야사에 의하면 조온마의 키는 5척으로 150cm 정도의 작은 키였다고 전해진다.

 

趙溫馬 亂色氣(조온마 난색기) :

1. 경거망동한 사람에게 충고할 때 쓰는 말.

2. 조온마의 키가 매우 작았으므로 작은 사람을 일컫는 말로 쓰이기도 한다.

 

주의 :

이 고사성어는 빠르게 발음이 되었다고 한다.

 

 

5. 善漁夫非取(선어부비취)

 

옛날 중국 원나라때의 일이다.

어떤 마을에 한 어부가 살았는데...

 

그는 너무나도 착하고 어질어서 정말 법 없이도 살 수 있는 정도였다.

그래서 항상 그는 마을사람들로부터 신망이 두터웠고, 그를 따르는 사람들이 끊이지 않았다.

 

그러던 어느 날 그 마을에 새로운 원님이 부임하게 되었는데...

그는 아주 포악한 성격의 소유자였다.

 

그 원님은 부임한 뒤 그 마을에 한 착한 어부가 덕망이 높고 마을 사람들의 신임을 얻고 있다는 사실을 알고 괴로워하기 시작했다.

 

'어떻게 하면 저 어부를 제거 할 수 있을까?'

한참을 생각하다가, 원님은 묘안을 하나 짜내게 되었다.

 

그 어부의 집 앞에 몰래 귀한 물건을 가져다 놓고 그 어부가 그 물건을 가져 가면 누명을 씌워 그 어부를 죽일 계획을 세운것이다.

 

첫 번째로 그는 그 어부의 집 앞에 쌀 한 가마니를 가져다 놓았다.

하지만 그 어부는 하루가 지나고, 이틀이 지나도 그 쌀 가마니를 거들떠 보지도 않는 것이었다.

그래서 원님은 두 번째로 최고급 비단을 어부의 집 앞에 가져다 놓았다.

그러나 결과는 마찬가지였다.

 

몸이 달을때로 달은 원님은 최후의 수단으로 커다란 금송아지 한 마리를 집 앞에 가져다 놓았다.

그러나 어부에게는 금송아지마저 소용이 없었다. 어부가 손끝 하나 대지 않은 것이다.

 

그러한 어부의 행동에 화가 난 원님은 그 자리에서 이렇게 탄식을 했다.

 

`선어부비취`(善漁夫非取)...착한 어부는 아무것도 가지지 않는구나.

그 뒤로 어부에게 감명받은 원님은 그 어부를 자신의 옆에 등용해, 덕으로써 마을을 다스렸다고 전해진다.

 

善漁夫非取(선어부비취) :

자신이 뜻한대로 일이 잘 이루어지지 않을 때 약간 화가 난 어조로 강하게 발음한다.

 

이 고사성어는 그 때 당시 중국 전역에 퍼졌고, 급기야는 실크로드를 타고 서역으로까지 전해졌으며...

 

오늘날에는 미국, 영국 등지에서 'son of a bitch' 로 자주 쓰이고 있다고 한다.

 

 

 

6. 漁走九里(어주구리)

 

옛날 한나라 때의 일이다.

어느 연못에 예쁜 잉어가 한마리 살고 있었다.

그러던 어느 날.

어디서 들어왔는지 그 연못에 큰 메기 한 마리가 침입하게 된 것이다.

 

그 메기는 예쁜 잉어를 보자마자 잡아 먹으려고 했다.

잉어는 연못의 이곳 저곳으로 메기를 피해 헤엄을 쳤다.

하지만 역부족이었다.

 

굶주린 메기의 추격을 피하기에는...

피하다 피하다 못한 잉어는 초어적(?)인 힘을 발휘하게 된다.

 

잉어는 자기도 모르는 사이에 뭍에 오르게 되고, 뭍에 오르자 마자 꼬리를 다리삼아 냅다 뛰기 시작했다.

메기가 못 쫓아 오는걸 알게 될 때까지 잉어가 뛰어간 거리는 약 구리 정도였을까? 암튼 십리가 좀 안 되는 거리였다.

 

그때 잉어가 뛰는 걸 보기 시작한 한 농부가 잉어의 뒤를 쫓았다.

잉어가 멈추었을때 그 농부는 이렇게 외쳤다.

 

`어주구리(漁走九里)`...고기가 구리를 달려왔다...

 

그리고는 힘들어 지친 그 잉어를 잡아 집으로 돌아가 식구들과 함께 맛있게 먹었다는 얘기이다.

 

어주구리(漁走九里) :

능력도 안 되는 이가 센척하거나 능력밖의 일을 하려고 할 때 주위의 사람들이 쓰는 말이다.

 

이 고사성어는 말할 때 약간 비꼬는 듯한 말투로 약간 톤을 높여 말하면 아주 효과적이다.

 

 

Posted by sehee

가자~ 집으로

2009/08/26 21:24

D-1

Go Go~ Korea~~

Posted by sehee

이번 출장 마지막 주 월요일이다.
처음 와본 폴란드 그리고 바르샤바...
낯설지만 나름 매력있는 곳인 것 같다.

생각하려고 한 만큼 많이 생각하지 못했고,
하려고 계획한 만큼 잘 하지 못했지만,
이제 돌아갈 시간이 다 되어간다.

혼란스러운 생각들은 돌아가서 여행하며 정리해봐야지.


폴란드
주소 해외여행지 유럽 동유럽
설명 동부 유럽에 있는 국가
상세보기

Posted by sehee

Socket Option

2009/08/24 04:04
** Generic Socket Options

1. SO_BROADCAST
 브로드 캐스팅을 할때 사용하는 옵션으로 UDP로만 사용할수 있으며 TCP로는 사용이 불가하다. 주소지정할때 브로드 캐스트 주소로 지정해야 하며(INADDR_BROADCAST이 바람직) 그렇지 않을 경우 에러가 발생한다.
 
2. SO_DEBUG
 TCP에서만 사용할수 있다. 커널은 주고 받는 tcp패킷에 대한 세부 정보를 저장하고 있다.

3. SO_DONTROUTE
 정상적인 라우팅 경로를 거치지 않게 한다. 만일 로컬 머신에서 목적지 주소를 정할수 없다면
ENETUNREACH가 리턴된다.
 (예를 들어, Point-to-Point Link 또는 Shared Network이 아닌 경우 ENETUNERACH가 리턴된다. 여기서 Point-to-Point Link는 오직 컴 두대가 연결된 것을 말하고 Shared Network은 허브로 연결된 네트워크를 말한다. 허브와 라우터의 차이점에 대해서 알아야 하는데 이것은 지식인;;;을 검색해 보면 나온다. 영어가 되면 구글로. 저는 지식인에서:-[ )

4. SO_ERROR
 소켓에 에러가 발생했을경우 so_error 변수에 에러값을 설정한다.
 1) select를 사용하고 있었다면 select가 에러를 리턴한다.
 2) signal-driven I/O를 사용하고 있었다면 SIGIO 신호가 발생한다.

5.
SO_KEEPALIVE
 주로 서버에서 클라이언트들의 연결상태를 확인하기 위해 사용한다.
 SO_KEEPALIVE옵션은 설정되어 있을때 tcp 소켓이 두시간동안 테이터 교환이 없다면 keepalive probe를 보낸다. 이 probe를 받은 peer는 반드시 응답해야 한다.

three scenarios:
 1) peer가 받기로 예정된 ACK로 응답하면 프로그램은 이것에 대한 통지를  따로 받지 않는다(모든 것이 정상이기 때문에). 비활성 상태가 2시간이 지속되면 새로운 probe를 보낸다.
 2) peer가 RST로 응답하면 TCP 커넥션에게 peer가 연결을 잃었거나 재부팅 되었다는 것을 의미한다.
 3) 응답이 없으면 일정한 시간을 기다린후 ETIMEOUT 에러 메시지를 내보낸다. 그러나 keppalive probe에 대해 ICMP 에러(host unreachable)가 되돌아 오면 이것은 EHOSTUNREACH 에러를 반환한다.

6. SO_LINGER
 소켓을 닫을 경우 send buffer 있는 데이터를 어떻게 처리할지 정할 수 있다. 기본값은 클로즈를 할 경우 바로 리턴하고 데이터가 있다면 보내려고 시도한다.

7.
SO_OOBINLINE
 SO_OOBINLINE 소켓 옵션이 설정되면, 송신된 모든 OOB 자료는 정상 자료 스트림에 저장된다. 수신함수에 MSG_OOB 플래그를 지정되어 있는 경우 [EINVAL] 오류가 리턴된다. (OOB 데이터를 읽을 수 없다.)
 
8.
SO_RCVBUF, SO_SNDBUF
 버퍼 크기를 조절한다.

9.
SO_RCVLOWAT, SO_SNDLOWAT
 select()가 readable 으로 셋되기 위한 데이터의 양을 설정해 준다. 기본적으로 tcp, udp가 readable 되기 위한 데이터의 총 양은 1byte이다. 이것을 변경해 줄수 있다. select()가 버퍼의 남은 공간의 총량이 일정 수준 이상이 되었을때 writable이 되는데 데이터의 공간을 지정할수 있다.

10.
SO_RCVTIMEO, SO_SNDTIMEO
 소켓에 데이터를 읽거나 쓸때 일정한 시간내에 완료 되지 않으면 에러를 리턴하게 한다.  

11.
SO_REUSEADDR, SO_REUSEPORT
 SO_REUSEADDR 옵션은 4가지의 다른용도로 사용된다.

 1)  포트에 연결이 남아 있더라도 listening server 가 그 포트로 binding 할 수 있다. 이와 같은 경우 SO_REUSEADDR 옵션이 설정되어 있지 않으면 bind가 실패하는 경우가 있다.
 2) 각각의 instance가 다른로컬 IP주소로 bind하는 경우, 같은 서버의 여러개의 instance가 존재할 수 있도록 허용
 3) 각각의 bind가 다른 로컬IP주소를 지정하는 경우, 하나의 프로세스가 여러개의 소켓을 하나의포트로 binding하도록 함
 4) UDP 소켓의 경우 completely duplicate binding을 가능하도록 함

12. SO_TYPE
 이 옵션은 소켓 타입을 리턴한다.(SOCK_STREAM, SOCK_DGRAM과 같은)
 일반적으로 소켓을 상속받은 프로세스가 시작할때 사용한다.

13. SO_USELOOPBACK
 소켓에서 보내지는 모든 패킷의 사본을 받게 됨
Posted by sehee

HTTP 1.1 응답코드값


 자세한건 RFC2616 문서를 보세요.

(Request For Comments :

http://www.rfc-editor.org/cgi-bin/rfcdoctype.pl?loc=RFC&letsgo=2616&type=ftp&file_format=txt

http://www.w3.org/Protocols/rfc2616/rfc2616.html )


1xx : 안내코드
100 : CONTINUE
101 : SWITCHING_PROTOCOLS , 규약을 전환
102 : PROCESSING


2xx : SUCCESS에 관한 코드
200 : OK , 성공적으로 요구를 전달하였음.
201 : CREATED , 요구가 충족되어 새로운 자원을 생성하였음
202 : ACCEPTED , 요구가 접수되었으며 아직 처리가 완료되지는 않았음. (단순한 접수여부이며 처리의 성공여부는 아님)
203 : NON_AUTHORITATIVE Information , 인증되지 않은 정보 (서버에서 사용하도록 정의되지 않는 정보세트를 말함)
204 : NO_CONTENT , 클라언트 요구을 처리했으나 전송할 데이터가 없음

       (기존내용의 변화없는 추가적인 정보입력을 실행할 경우에 해당함)
205 : RESET_CONTENT , 내용을 reset
206 : PARTIAL_CONTENT , 부분적으로 요구를 완료하였음.
207 : MULTI_STATUS


3xx : REDIRECT에 관한 코드 (처리를 위해 추가적인 동작이 필요함)
300 : MULTIPLE_CHOICES , 복수 선택
301 : MOVED_PERMANENTLY , 요청한 자원이 영구한 URI가 할당되어 이동함.
302 : MOVED_TEMPORARILY , 요청한 자원이 별도의 임시 URI에 할당되어 이동함.
303 : SEE_OTHER , 다시 다른것을 참조함.
304 : NOT_MODIFIED , 별다른 변경이 없이 응답되었음
305 : USE_PROXY , 요청된 자원은 프락시를 통해야만 접근이 됨
306 : TEMPORARY_REDIRECT


4xx : CLIENT_ERROR에 관한 코드 (요구 메시지가 처리할 수 없을 때)
400 : BAD_REQUEST , 클라이언트의 요청을 서버가 이해하지 못함.
401 : UNAUTHORIZED , 요청에 대한 응답이 사용자인증을 필요로 할 경우.
402 : PAYMENT_REQUIRED  , 예약되어 있음
403 : FORBIDDEN , 금지됨 (요청은 이해하였으나 금지되어있는 요청임)
404 : NOT_FOUND , Request-URI를 찾을 수 없음
405 : METHOD_NOT_ALLOWED , URI에서 사용되지 않는 method를 요청함.
406 : NOT_ACCEPTABLE , 접수할수없음을 나타냄.
407 : PROXY_AUTHENTICATION_REQUIRED , 프락시에서 먼저 인증을 해야함.
408 : REQUEST_TIME_OUT , 요청한 시간내에 응답을 하지 못함.
409 : CONFLICT , 충돌 (어떠한 부분의 충돌로 응답하지 못함)
410 : GONE , 영구적으로 사용할 수 없는 경우에 해당하며 그렇지 않으면 401로 응답함.
411 : LENGTH_REQUIRED , 유효하지 못한 Content-Length로 요청을 하였음.
412 : PRECONDITION_FAILED , 전체조건 실패 ( 하나이상의 Request-Header에 기재된 내용이 실패됨)
413 : REQUEST_ENTITY_TOO_LARGE , 요구 entity가 너무커서 처리가 거부됨.
414 : REQUEST_URI_TOO_LARGE ,URI길이가 허용보다 커서 처리가 거부됨.
415 : UNSUPPORTED_MEDIA_TYPE ,  지원되지 않는 포맷으로 거부됨.
416 : RANGE_NOT_SATISFIABLE
417 : EXPECTATION_FAILED
422 : UNPROCESSABLE_ENTITY
423 : LOCKED
424 : FAILED_DEPENDENCY


5xx : SERVER_ERROR에 관한 코드 (서버가 요청을 처리하는 과정에서 문제발생)
500 : INTERNAL_SERVER_ERROR , 내부서버 오류 (잘못된 스크립트 실행과 같은 예상하지 못한 오류일 경우)
501 : NOT_IMPLEMENTED , 구현되지 않았음 (요청을 처리하는데 필요한 기능이 구현되지 않았음)
502 : BAD_GATEWAY , 나쁜 게이트웨이 (게이트웨이 서버가 올바르지 않은 응답을 수신 할 경우)
503 : SERVICE_UNAVAILABLE , 과부하 또는 여러가지 이유로 현재 요청을 처리하지 못함.

       (임시적이며 일정한 시간뒤에 정상적으로 서비스 가능)
504 : GATEWAY_TIME_OUT , 게이트웨이(또는 프락시)서버가 시간내에 요청의 처리를 완료하는 수신을 받지 못함.
505 : VERSION_NOT_SUPPORTED , 지원되지 않는 HTTP 버젼임.
506 : VARIANT_ALSO_VARIES
507 : INSUFFICIENT_STORAGE
510 : NOT_EXTENDED


601 : 접근불가. HTTP CONNECT TIMEOUT
ㅇ 3초내에 CP로 HTTP Connection을 하지 못한 경우
   (예) Network 이상, CP의 과부하로 인해 CP Web서버로 connection이 안될 때)

Posted by sehee
BSD Socket API(Application Programming Interface)를 이용한 프로그래밍

소켓은 소프트웨어로 작성된 통신 접속점이다. 네트워크 응용 프로그램은 소켓을 통하여 통신망으로 IP 패킷을 송수신하게 된다. 소켓은 응용 프로그램에서 TCP/IP 계층을 이용하는 창구 역활을 하고 있으며 응용 프로그램과 소켓 사이의 인터페이스를 소켓 인터페이스라고 한다.

유닉스에서 파일을 열면(open) int 타입의 정수를 리턴하는데 open문이 리턴한 정수를 파일기술자(file descriptor)라고 하며 프로그램에서 이 파일을 액세스할 때 해당 파일 기술자를 사용하면 된다. 파일기술자는 기술자 테이블(descriptor table)의 index 번호인데, 기술자 테이블이란 현재 open되어 있는 파일의 각종 정보를 포함하고 있는 구조체를 가리키는 포인터들로 구성된 테이블이다.

프로그램에서 소켓을 개설하면 파일기술자와 똑같은 기능을 하는 소켓기술자(socket descriptor)가 리턴되며 응용 프로그램에서 이 소켓을 통하여 목적지 호스트와 패킷을 송수신할 때 이 소켓기술자(소켓번호)를 사용하게 된다.

소켓을 이용하는 네트워크 응용 프로그램에서 상대방 세션과 IP 패킷을 주고받기 위해서는 다음의 다섯 가지 정보가 정해져야 한다.

1. 통신에 사용할 프토토콜(TCP 또는 UDP)

2. 자신의 IP 주소

3. 자신의 포트 번호

4. 상대방의 IP 주소

5. 상대방의 포트 번호

소켓 프로그래밍에서 첫번째로 해야 할 일은 통신 창구 역활을 하는 소켓을 만드는 것이다. 이것은 클라이언트와 서버에서 모두 필요한데 이를 위하여 socket() 시스템 콜을 이용한다. socket()이 성공적으로 수행되면 새로 만들어진 소켓번호를 리턴한다.

int socket

(

    int domain,   /* 프로토콜 체계 */

    int type,       /* 서비스 타입 */

    int protocol  /* 소켓에서 사용할 프로토콜 */

);

domain:

PF_INET 인터넷 프로콜 체계 사용

PF_INET6 IPv6 프로토콜 체계 사용

PF_UNIX 유닉스 방식의 프로토콜 체계 사용

PF_NS XEROX 네트워크 시스템의 프로토콜 체계 사용

PF는 Protocol Family

type: 서비스 타입

SOCK_STREAM 스트림 방식의 소켓 생성

SOCK_DGRAM 데이터그램 방식의 소켓 생성

SOCK_RAW raw 모드의 소켓 생성

protocol: 구체적인 프로토콜을 선택할 때 사용하는데 대부분의 응용 프로그렘에서는 0으로 지정하면 된다.

소켓을 이용하는 통신 객체(클라이언트 또는 서버)의 구체적인 주소를 표현하기 위해서는 주소 체계(address family), IP 주소, 포트 번호 세 가지가 지정되어야 하며 이 세 가지 정보를 소켓주소(socket address)라고 부른다. 소켓 프로그래밍에서는 소켓주소를 담을 구조체 sockaddr을 다음과 같이 정의하였으며 이것은 2바이트의 address family와 14바이트의 주소(IP 주소 + 포트 번호)로 구성되어 있다.

struct sockaddr

{

    u_short sa_family;    /* address family */

    char sa_data[14];    /* 주소(IP 주소 + 포트 번호) */

};

그런데 위에 정의된 sockaddr 소켓주소 구조체에 IP 주소, 포트 번호 등을 직접 쓰거나 읽기가 불편하므로 인터넷 프로그래밍에서는 sockaddr 구조체를 사용하는 대신 4바이트의 IP 주소와 2바이트의 포트 번호를 구분하여 액세스 할 수 있는 인터넷 전용 소켓주소 구조체 sockaddr_in을 주로 사용한다. 아래에 sockaddr_in 구조체의 정의를 나타냈는데 여기서는 다시 32비트의 IP주소를 저장하는 구조체 in_addr를 사용하고 있다.

struct in_addr

{

    u_long s_addr;    /* 32비트의 IP 주소를 저장할 구조체 */

}

struct sockaddr_in

{

    short sin_family;            /* 주소 체계 */

    u_short sin_port;           /* 16비트 포트 번호 */

    struct in_addr sin_addr; /* 32비트 IP 주소 */

    char sin_zero[8];         /* 전체 크기를 16바이트로 맞추기 위한 dummy */

}

sockaddr_in에서 주소 체계 sin_family로 선택할 수 있는 대표적인 것은 다음과 같으며 인터넷 주소 체계를 사용하려면 AF_INET을 선택하면 된다.

sin_family:

AF_INET 인터넷 주소 체계

AF_UNIX 유닉스 파일 주소 체계

AF_NS XEROX 주소 체계

AF는 address family(주소 체계)를 나타내는데, socket()으로 소켓을 개설할 때 프로토콜을 PF_INET 즉, 인터넷으로 지정한 경우에는 주소 체계로 AF_INET만을 사용할 수 있다. 한편 이 두 상수 PF_INET과 AF_INET의 값은 모두 2로 같으므로 편의상 이 두 표현을 혼용하기도 한다.

소켓프로그래밍의 개요

TCP(연결형) 소켓 프로그래밍 절차

클라이언트-서버 통신 모델에서는 항상 서버 프로그램이 먼저 수행되고 있어야 하는데, 서버는 socket()을 호출하여 통신에 사용할 소켓을 하나 개설하고 이 때 리턴된 소켓번호와 자신의 소켓주소를 bind()를 호출하여 서로 연결시켜 둔다. 서버에서 bind()가 필요한 이유는 소켓번호는 응용 프로그램이 알고 있는 통신 창구 번호이고, 소켓주소는 네트워크 시스템이 알고 있는 주소이므로 이들의 관계를 묶어 두어야(bind) 응용 프로세스와 네트워크 시스템간의 패킷 전달이 가능하기 때문이다.

다음에 서버는 listen()을 호출하여 클라이언트로부터의 연결 요청을 기다리는 수동 대기모드로 들어가며, 클라이언트로부터 연결요청이 왔을 때 이를 처리하기 위하여 accept()를 호출한다. 서버는 accept() 시스템 콜에서 기다리고 있다가 클라이언트가 connect()를 호출하여 연결요청을 해오면 이를 처리한다. 이 때 연결이 성공적으로 이루어지면 서버와 클라이언트가 데이터를 송수신할 수 있게 된다.

한편 클라이언트는 socket()을 호출하여 소켓을 만든 후 bind()를 부를 필요 없이, 서버에게 연결 요청을 보내기 위하여 connect()를 호출한다. 이 때 클라이언트는 접속할 상대방 서버의 소켓주소 구조체를 만들어 connect()의 함수 인자로 주어야 한다.

클라이언트에서 bind()를 호출할 필요가 없는 이유는 클라이언트 프로그램은 자신의 IP 주소나 포트 번호를 다른 클라이언트 또는 서버가 미리 알고 있을 필요가 없기 때문이다. 즉, 대부분의 클라이언트는 포트 번호를 특정한 값으로 지정할 필요가 없다. 그러나 서버는 미리 지정한 포트 번호를 통하여 클라이언트가 알고 있는 포트 번호를 bind()로 연결해 두는 것이 필수적이다.

클라이언트가 bind()를 사용하면 오히려 클라이언트 프로그램의 범용성이 떨어지게 되는데 왜냐하면 같은 포트 번호를 사용하는 클라이언트 프로그램이 하나의 컴퓨터에 두 개 이상 실행되면 포트 번호 중복 사용으로 인하여 에러가 발생하기 때문이다.

클라이언트 프로그램

클라이언트는 connect()를 호출하기 전에 연결하고자 하는 서버의 주소를 지정하여야 하는데, 4바이트의 IP 주소와 2바이트의 포트 번호를 포함하는 소켓주소 구조체 sockaddr_in를 작성하여야 한다. 이 서버의 소켓주소 구조체를 사용하여 서버에게 접속을 요청하기 위하여 connect()를 호출한다. connect()는 상대방 즉, 서버의 IP 주소와 포트 번호를 명시하여 socket()으로 얻은 소켓번호로 호출하면 된다.

int connect(int s, const struct sockaddr *addr, int addrlen);

connect()를 호출하면 TCP가 소켓주소 구조체 *addr에 지정된 서버의 IP 주소와 포트 번호로 연결을 시도하여 연결이 성공하면 0을 리턴한다. 실패하면 -1을 리턴하며 전역변수 errno에 에러코드가 들어 있게 된다. 클라이언트가 호출하는 connect()가 성공적으로 연결되려면 서버에서는 accept()를 호출해 두고 있어야 한다. connect() 시스템 콜 호출 중에 에러가 발생하였을 때는 바로 다시 connect()를 호출하지 말고 소켓을 close()로 닫고 새로운 소켓을 socket()으로 만든 후 사용하는 것이 안전하다. 연결형 클라이언트에서는 connect()를 호출할 때에 TCP가 임의의 포트 번호를 지정해 주기 때문에 bind()를 사용할 필요가 없다.

서버 프로그램 작성

socket() 시스템 콜을 호출하여 생성된 소켓은 그 응용 프로그램 내에서 유일한 번호인 소켓번호를 배정받는다. 그러나 이 번호는 응용 프로그램만 알고 있는 번호이므로 이 프로그램이 컴퓨터 외부와 통신을 하려면 이 소켓번호와 TCP/IP 시스템이 제공하는 소켓주소(IP 주소 + 포트 번호)를 연결해 두어야 하며 이를 위하여 bind()가 사용된다. 

int bind(int s, struct sockaddr *addr, int len);

서버에서 bind()가 반드시 필요한 이유는 임의의 클라이언트가 서버의 특정 프로그램이 만든 소켓과 통신을 하려면 그 소켓을 찾을 수 있어야 하며, 따라서 서버는 자신의 소켓번호와 클라이언트가 알고 있는 자신의 IP 주소 및 포트 번호(즉, 서버의 소켓주소)를 미리 서로 연결시켜 두는 것이 필요하기 때문이다.

서버는 클라이언트로부터의 연결요청을 받아들이기 위하여 listen()을 호출해야 한다.

int listen(int s, int log);

위에서 인자 log는 서버에서 accept()를 처리하는 동안 대기시킬수 있는 connect()의 요청 수를 지정한다. 즉, 클라이언트가 요구한 연결요청을 최대 log개까지 기다리게 할 수 있다는 것이다. 예를 들어 listen(s, 2);는 서버가 최대 2개의 connect() 요청을 대시시킬 수 있으며, 세번째 이후의 connect() 요청은 거절하여 클라이언트가 이 사실을 바로 알 수 있도록 해준다. 한편 listen()은 소켓을 단지 수동 대기모드로 바꾸는 것이므로 listen()은 즉시 리턴되는데 성공시에는 0, 실패시에는 -1이 리턴된다.

서버가 listen()을 호출한 이후에 어떤 클라이언트에서 connect()로 이 서버에 연결요청을 보내면 이를 처리하기 위해서 서버는 accept()를 호출해 두어야 한다. accept()의 수행이 성공하면 접속된 클라이언트와의 통신에 사용할 새로운 소켓이 만들어지고 이 소켓번호가 리턴되며 실패시에는 -1이 리턴된다. 그런데 서버는 이 클라이언트와 통신하기 위하여 accept()가 리턴한 소켓번호를 사용한다는 것을 주의하여야 한다. accept()는 또한 연결된 클라이언트의 소켓주소 구조체와 구조체의 길이의 포인터를 함수 인자로 리턴해 준다.

int accept(int s, struct sockadddr *addr, int *addrlen);

바이트 순서(byte ordering)

바이트 순서(byte ordering)에는 호스트 바이트 순서와 네트워크 바이트 순서 두 가지가 있다. 호스트 바이트 순서는 컴퓨터 내부 메모리에 숫자를 저장하는 순서를 말하는데, 이것은 컴퓨터의 CPU의 종류에 따라 다르다. 예를 들어 두 바이트로 구성된 십진수 50146의 경우 HEX로 0xC3E2이며 이것은 80x86 계열의 CPU에서는 E2, C3의 순서로(즉, 하위 바이트부터) 메모리에 저장되고 MC6800 계열의 CPU에서는 C3, E2의 순서로 메모리에 저장된다. 전자를 하위 바이트(즉 little end)가 메모리에 먼저 잡힌다고 하여 little-endian이라고 하고 후자를 상위 바이트(즉, big end)가 메모리에 먼저 잡힌다고 하여 big-endian이라고 부른다.

네트워크 바이트 순서는 포트 번호나 IP 주소와 같은 정보를 바이트 단위로 네트워크로 전송하는 순서를 말하는데 네트워크 바이트 순서는 high-order 바이트부터 전송하기로 정했다(즉, big-endian 순서라고 할 수 있다). 예를 들어 2바이트의 수 0xC3E2의 경우 C3, E2의 순서로 상위 바이트부터 전송된다. 즉, 80x86 계열의 CPU가 사용하는 호스트 바이트 순서는 네트워크 바이트 순서와 다르다. 따라서 80x86 계열의 컴퓨터에서 네트워크를 통하여 전송한 숫자는 MC68000의 계열의 컴퓨터가 수신하면 순서가 바뀌게 된다.

이러한 문제를 해결하기 위하여 컴퓨터 내부에서 사용하던 숫자를 네트워크로 전송하기 전에 htons() 함수를 사용하여 모두 네트워크 바이트 순서로 바꾸어야 하고, 반대로 네트워크로부터 수신한 데이터는 ntohs() 함수를 사용하여 자신의 호스트 바이트 순서로 항상 바꾸어야 한다. 즉 모든 컴퓨터가 네트워크 바이트 순서를 지켜 숫자를 전송함으로써 이것이 어떤 종류의 컴퓨터에서 만들어진 것인지 알 필요가 없도록 하는 것이다.

바이트 순서를 바꾸는 함수에는 변환할 바이트의 길이에 따라 다음과 같이 두 가지 종류가 있다.

unsigned short integer 변환 (2바이트 크기)

  htons(): host-to-network 바이트 변환

  ntohs(): network-to-host 바이트 변환

unsigned long integer 변환 (4바이트 크기)

  htonl(): host-to-network 바이트 변환

  ntohl(): network-to-host 바이트 변환

주의할 것은, 바이트 순서를 맞추는 것이 필요한 경우는 포트 번호 등의 숫자를 네트워크로 전송할 때이며 텍스트 문서나, 바이너리 파일 등 일반 사용자 데이터는 바이트 변환이 필요다는 것이다. 왜냐하면 일반 데이터는 메모리(버퍼)에 저장되었다가 바이트 단위로 메모리 앞 주소부터 차례대로 전송되며 수신측에서도 수신된 바이트를 메모리에 차례대로 저장하기 때문이다.

IP 주소 변환

IP 패킷을 네트워크로 실제로 전송할 때에는 32비트의(binary) IP 주소만 사용할 수 있다.

dotted decimal로 표현된 192.203.144.11을 32비트의 IP 주소로 변환하려면 inet_addr()함수를 사용하고, IP 주소를 dotted decimal로 변환하려면 inet_ntoa()를 사용한다.

#include <arpa/inet.h>

char *inet_ntoa(struct in_addr addr); //IP 주소 -> dotted decimal

in_addr inet_addr(const char *host); //dotted decimal -> IP 주소

close(), 소켓 닫기

소켓의 사용을 마치려면 해당 소켓 번호를 지정하여 close()를 호출하여 소켓을 종료하여야 한다. close()는 클라이언트나 서버 중 누구나 먼저 호출할 수 있다. close()를 호출한 시점에 서버나 클라이언트의 송신 버퍼에 들어 있으나 아직 전송되지 못한, 또는 네트워크 내에서 전달중인 패킷들이 있을 수 있다. close()는 디폴트로 이러한 패킷들을 모두 처리한 후에 소켓을 닫게 되어 있다. 그러나 이러한 패킷들을 보다 구체적으로 처리하기 위하여 close()를 호출하기 전에 shutdown() 시스템 콜을 아래와 같이 사용할 수 있다.

shutdown(s, direction);

위에서 s는 닫을 소켓번호이고, direction은 1이면 패킷의 전송을 종료하고 0이면 수신을 종료하며 2이면 송수신을 모두 종료하게 한다.

UDP 소켓에서는 close()를 호출하면 단순히 사용하던 소켓을 닫는 작업을 수행한다.

소켓의 동작모드

소켓의 동작모드에는 blocking, non-blocking, 비동기(asynchronous) 모드 세 가지가 있다. 소켓을 처음 생성하면 blocking 모드가 되는데 blocking 모드의 소켓이란 이 소켓에 대해 어떤 시스템 콜을 호출하였을 때 네트워크 시스템(즉, TCP/IP)이 동작을 완료할 때까지 그 시스템 콜에서 프로세스가 멈추어 있는 모드를 말한다. 소켓 관련 시스템 콜 중에 block될 수 있는 것은 listen(), connect(), accept(), recv(), read(), write(), recvfrom(), sendto(), close()등이다.

Non-blocking 모드의 소켓이란, 소켓 관련 시스템 콜에 대하여 네트워크 시스템이 즉시 처리할 수 있으면 바로 결과를 리턴하고, 즉시 처리할 수 없는 경우라도 시스템 콜이 바로 리턴되어 응용 프로그램이 block 되지 않게 하는 소켓을 말한다. 비동기 모드는 소켓에서 어떤 I/O 변화가 발생하면(데이터의 도착 등) 그 사실을 응용 프로그램이 알 수 있도록 하여 read(), write()와 같은 원하는 동작을 실행할 수 있게 하는 모드를 말한다.

소켓을 non-blocking 모드로 사용하는 경우는 일반적으로 어떤 시스템 콜이 성공적으로 실행될 때까지 계속 루프를 돌면서 확인하는 방법(폴링)을 사용한다.

소켓을 비동기 모드로 사용하는 방법은 일반적으로 select() 함수를 이용하는 방법이 널리 사용되는데 이것은 I/O 변화가 발생할 수 있는 소켓 전체를 대상으로 select()를 호출해 두면 그 중 임의의 소켓에서 I/O 변화가 발생되었을 때 select() 문이 리턴되고 이 때 원하는 소켓 시스템 콜을 호출하는 방법이다.

select() 시스템 콜

select()는 소켓에서 I/O 변화를 기다리다가 I/O 변화가 발생하면 리턴되는데 응용 프로그램에서는 select()가 리턴되었을 때 어떤 소켓에서 어떤 I/O 변화가 발생하였는지를 확인하여 필요한 작업을 처리하게 된다.

int select(int n, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *t);

n: select 함수가 검사햐여야 할 소켓의 수

rfds: 데이터 수신 가능성을 검사할 fd_set 구조체의 포인터

wfds: 데이터 송신 가능성을 검사할 fd_set 구조체의 포인터

efds: 예외 상황을 검사할 fd_set 구조체의 포인터

t: 최대 대시 시간(NULL이면 Blocking 모드로 동작)

각각 fd_set 타입 구조체에 I/O 변화를 감지할 소켓(또는 파일)번호를 1로 세트하여 select()를 호출해 두면 해당 조건이 만족되는 순간 select()문이 리턴된다.

fd_set 타입의 구조체의 값을 편리하게 지정하기 위하여 특정 소켓의 I/O 변화 감지를 선택하거나 취소하기 위한 매크로가 제공된다.

FD_ZERO(fd_set *fdset) *fdset의 모든 비트를 지운다.
FD_SET(int fd, fd_set *fdset) *fdset 중 소켓 fd에 해당하는 비트를 1로 한다.
FD_CLR(int fd, fd_set *fdset) *fdset 중 소켓 fd에 해당하는 비트를 0으로 한다.
FD_ISSET(int fd, fd_set *fdset) *fdset 중 소켓 fd에 해당하는 비트가 세트되어 있으면 양수값인 fd를 리턴한다.

소켓옵션

TCP/IP 프로토콜의 기능을 보다 구체적으로 활용하거나 소켓의 세부적인 동작 특성을 바꾸려면 소켓 옵션을 변경하는 것이 필요한데, 소켓 옵션을 변경하려면 다음과 같이 setsockopt() 함수를 사용한다.

int setsockopt(int s, int level, int opt, const char *optval, int option);

s: 옵션을 바꿀 소켓번호

level: 프로토콜 레벨을 지정. 소켓의 일반적인 옵션 지정이면 SOL_SOCKET, IP 프로토콜에 관한 것이면 IPPROTO_IP를, TCP에 관한 내용이면 IPPROTO_TCP를 각각 선택한다.

opt: 선택할 옵션을 지정

optval: 옵션 지정에 필요한 값의 포인터

optlen: optval의 크기

옵션 중에는 어떤 상태의 선택 또는 취소 둘 중 하나를 택하는 옵션들이 있는데 이러한 옵션 지정시에는 *optval 값이 1이면 선택이고 0이면 취소가 된다.

소켓 옵션 지정의 종류

소켓주소 재사용 옵션(SO_REUSEADDR)

자신의 소켓주소(IP 주소와 포트 번호)가 여러 프로세스에 의하여 또는 한 프로세스 내의 여러 소켓에서 중복되어 사용되는 것을 허용하는 옵션이다. 이 옵션은 구체적으로 다음과 같은 네 가지 목적으로 사용된다.

1. 예를 들어 어떤 TCP 서버 프로그램에서 자식 프로세스가 서비스의 처리를 담당하고 있는 도중에 부모 프로세스가 종료되었다가 다시 시작하게 되면 "포트 번호가 사용중"이라는 오류가 발생하게 된다(자식 프로세스가 그 포트 번호를 사용하고 있기 때문에). 이러한 오류를 피하기 위하여 TCP 서버에서 fork()를 이용하는 경우에는 특정 포트 번호(즉, 특정 소켓주소)가 재사용될 수 있다는 옵션을 지정해 두어야 한다. 이 소켓주소 재사용 옵션 지정은 소켓을 만든 후 bind()를 하기전에 해야 한다.

2. 같은 포트 번호를 사용하면서 IP 주소는 서로 다른 서버를 한 호스트 내에서 여러 개 실행시킬 때 필요하다. 이것은 IP 주소가 여러 개인 (multihomed) 호스트에서 동일한 포트 번호를 사용하는 서버(예를 들면 포트 번호가 80인 HTTP 서버)를 여러 개 실행시킬 때 사용된다. 물론 각 서버는 별도의 소켓주소(즉, 서로 다른 IP 주소)를 사용하여 bind()를 해 두어야 한다.

3. 위의 2번과 같으나 하나의 프로세스에서 여러 소켓을 개설하고 모두 같은 포트 번호를 사용하도록 할 때 필요하다. 이 때에도 소켓별로 각각 다른 IP 주소를 지정하여 bind()하여야 한다.

4. 여러 프로세스에서(또는 한 프로세스 내의 여러 소켓에서) 동일한 IP 주소와 포트 번호를 bind()하는 것을 허용할 때 사용된다. 이렇게 IP 주소와 포트 번호가 모두 중복되는 바인딩을 completely duplicate binding이라고 하는데 이것은 TCP에서는 전혀 사용할 수 없고 UDP에서만 사용 가능하다. 이것의 대표적인 사용 예는 멀티캐스트 패킷을 수신하기 위한 경우이다. 예를 들어 하나의 호스트 내에서 여러 멀티캐스트 가입자들이 같은 프로그램을 실행시키고 있을 때 각 멀티캐스트 이용 프로그램이 동일한 패킷을 수신할 수 있도록 하기 위하여 이러한 옵션 지정이 필요하다.

* 특정 통신 계층에서 다루는 데이터 단위를 프로토콜 데이터 단위(PDU: Protocol Data Unit)라고 하는데, 링크 계층의 PDU를 프레임(frame), 네트워크 계층의 PDU를 패킷(packet)이라고 부른다. IP 계층의 PDU를 데이터그램이라고 한다. 트랜스포트 계층이 다루는 PDU를 메시지라고 한다.

Posted by sehee

Way Back Into Love

2007/05/11 00:55



 

Way Back Into Love
사랑 안으로 돌아 가는 길


I've been living with a shadow overhead
난 내 머리 위로 그림자가 드리워진 채로 살았어. 

I've been sleeping with a cloud above my bed
난 내 침대 위로 구름이 드리워진 채로 잠을 잤어.

I've been lonely for so long
난 너무나 오랫동안 외로웠어.

Trapped in the past, I just can't seem to move on
과거에 갇힌채, 난 도저히 나아갈수가 없었지.


I've been hiding all my hopes and dreams away
난 내 꿈과 희망을 숨겨두고만 있었지.

Just in case I ever need em again someday
혹시라도 내가 그것들이 필요할까봐서..

I've been setting aside time
난 시간에 벗어난 곳에 나 자신을 두었어.

To clear a little space in the corners of my mind
내 머릿속의 작은 공간을 지워 버리기 위해...


All I want to do is find a way back into love
사랑 안으로 돌아 갈수 있는 방법을 찾고 싶을 뿐이야.

I can't make it through without a way back into love
사랑 안으로 돌아 갈수 있는 방법 없이는 이대로 이겨낼수 없는걸...

Oh oh oh
오 오 오


I've been watching but the stars refuse to shine
오랫동안 쳐다 보았지만 별들은 반짝이길 거절했어.

I've been searching but I just don't see the signs
오랫동안 찾아 보았지만 아무런 흔적도 찾을수 없었어.

I know that it's out there
다 존재 한다는것은 알아.

There's got to be something for my soul somewhere
저기 어딘가에 내 영혼을 위한 무언가가 있을텐데...


I've been looking for someone to shed some light
누군가가 빛을 쏘아 주기를 기다렸어.

Not just somebody just to get me throught the night
밤을 지새울 아무나가 아닌...

I could use some direction
난 누군가의 도움을 조금이나마 쓸수 있을텐데..

And I'm open to your suggestions
그리고 난 당신의 제안도 받아들일수 있어.


All I want to do is find a way back into love
사랑 안으로 돌아 갈수 있는 방법을 찾고 싶을 뿐이야.

I can't make it through without a way back into love
사랑 안으로 돌아 갈수 있는 방법 없이는 이대로 이겨낼수 없는걸...

And if I open my heart again
그리고 만약 내가 마음을 또다시 연다면...

I guess I'm hoping you'll be there for me in the end
최후에는 당신이 내 곁에 있어 줄거라고 생각해요.


There are moments when I don't know if it's real
진실인지 거짓인지 헷갈리는 순간들이 있어요.

Or if anybody feels the way I feel
혹은 내가 느끼는 이 감정을 누군가도 느끼고 있을까... 

I need inspiration
난 영감이 필요해요

Not just another negotiation
또 하나의 협상이 아닌...


All I want to do is find a way back into love
사랑 안으로 돌아 갈수 있는 방법을 찾고 싶을 뿐이야.

I can't make it through without a way back into love
사랑 안으로 돌아 갈수 있는 방법 없이는 이대로 이겨낼수 없는걸...

And if I open my heart to you
만약 내가 당신에게 마음을 연다면

I'm hoping you'll show me what to do
당신이 내게 뭘 해야 하는지 보여주길 바래요.

And if you help me to start again
그리고 당신이 내가 새로 시작 할수 있게 도와 준다면

You know that I'll be there for you in the end
최후에는 내가 당신의 곁에 있어 줄거라는걸 알잖아요


Posted by sehee

Don't Write Me Off

2007/05/11 00:52


Don't Write Me Off

사용자 삽입 이미지

It's never been easy for me to find the words to go along with the melody
But this time there's actually something on my mind
so please forgive these few brave awkward lines


(멜로디와 어울리는 가사를 찾는다는게 나에게 쉽지만은 않았죠
이번에는 정말로 머릿속에 떠오르는 것이 있죠

그러니 이 용감하고 서투른 말들을 용서해 주세요)

 
since I met you my whole life has changed
It's not just my furniture you've rearranged
I was living in the past but somehow you've brought me back
and I haven't felt like this since before Frankie said "Relax"
 
(당신을 만나고부터 내 인생 모든 것이 바뀌었죠
당신이 정리해준건 단순히 내 가구들 뿐만이 아니죠
과거에서 살고 있던 나를 그대는 다시끔 데려와 주었죠
Frnakie가 'Relax'를 부르기 전 그 때 이후 이런 느낌은 처음이죠)
 
And Now I know based on my track record
I might not seem like the safest bet
All I'm asking you is don't write me off just yet
 
(나의 앨범 판매 기록을 봐서 내가 그다지 안전한 선택이 아니라는건 알지만
그대에게 내가 바라는 것은 단지.. 아직은 날 지워버리지 말아주세요)

For years I've been telling myself the same old story
that I'm happy to live off my so-called full of glories
 But you've given me a reason to take another chance
now I need you despite the fact that you've killed all my plants
 
(오랜 세월동안 스스로에게 똑같은 말만 되풀이해왔죠
나의 영광의 날들에 의존하며 살아가는 것만으로도 행복하다고
하지만 당신은 내가 또 다른 기회를 잡을 수 있도록 이유를 주었죠
이젠 그대가 필요하죠 비록 그대가 우리집 화초들을 다 죽여버렸지만 말이에요)

And Now I know I've already blown more chances than anyone should ever get
All I'm asking you is don't write me off just yet
Don't write me off just yet
 
(그대에게 바라는 것은 단지.. 아직은 날 지우지 말아주세요
아무도 가져서는 안 될 그런 많은 기회를 이미 날려버렸다는 것은 알지만
아직은 날 지우지 말아주세요)
Posted by sehee
"인간은 본래 무엇인가? 무한에 비하면 무고, 무에 비하면 모든 것이며, 무와 모든 것 사이의 중간적인 것이다."
§블라제 파스칼의 팡세중에서


파스칼(1623 ~ 1662)은 과학자인 동시에 수학자 입니다. 과학자로서의 파스칼은 무의 본질, 즉 진공을 연구했으며 수학자로서의 파스칼은 무한의 본질 즉, 을 연구했습니다.

파스칼은 무한에 0을 접목시킴으로서 신을 발견했으며, 확률론적으로 지옥에 갈 위험을 헷지(hedge)하기 위해서는 신을 믿는 것이 좋다라는 결론에 도달했습니다.

오늘의 이야기는 파스칼과 신에관한 확률론적 도박입니다.

도박에서 기대값을 분석하는 것과 마찬가지로, 파스칼은 그리스도를 구세주로 받아들이는 것에대한 기대값을 계산 했습니다.

☞투자에대한 기대값 분석은 제글
방정식과 경제이해를 참조하시기 바랍니다.

우선 신이 존재할 확률을 50대 50이라고 가정하고, 파스칼은 기독교 신자의 길을 택하는 경우 만일 신이 없다면 죽어서 무(無)로 사라지게 되고, 신이 있다면 죽어서 영생을 얻게 된다고 보았습니다.

그럼므로 기독교도인이 될 경우 기대값은 다음과 같습니다.

무로 사라질 확률의 기대값 :

천국에 갈 확률의 기대값 :

결과적으로 기독교인의 기대값은 두 값을 더한 가 되는 것입니다.

무한대의 1/2은 여전히 무한대이므로, 기독교인이 되는 것의 가치는 무한대라고 볼 수 있습니다.

파스칼이 계산한 것은 여기까지 이지만, 무신론자의 경우라면 어떻게 될까요?

만일 실제로 신이 존재하지 않는다면 옳은 선택을 한 것입니다.

그런데 얻는 것은 결국 무(無) 이므로 얻는 것은 아무것도 없습니다. 왜냐하면 신이 없다면 천국도 없기때문입니다.

반면, 실제로 신이 존재한다면 영원히 지옥(?!!)으로 떨어지게 됩니다. 즉, 영생으로보면 마이너스 무한대가 되는 것입니다.

무신론자의 기대값은 다음과 같습니다.

무로 사라질 확률의 기대값 :

지옥에 갈 확률의 기대값 :

그러므로 기대값은 마이너스 무한대가 됩니다.

올바른 선택[신이 존재하지 않는다는 선택]을 하였다고 해도, 그 결과는 매우 불행하게 되는 것입니다.

그래서 파스칼은 현명한 사람은 기독교를 선택하게 된다고 주장하는 것입니다.

그런데, 여기서 만약 신이 존재할 확률이 십만분의 일 또는 백만분의 일이라고 가정하면 어떻게 될까요?

결과적으로 기대값에는 변화가 없게 됩니다.

예를 들면, 기독교인이 될경우,

무로 사라질 확률의 기대값 :

천국에 갈 확률의 기대값 :

으로 기대값은 두 값을 더한 가 됩니다. 물론 무신론자의 기대값은 가 됩니다.

만일 저처럼 다른 종교를 믿는 다면 어떻게 될까요?

지옥에 갈 확률이 줄어들지는 모르지만[예를 들면 윤회], 결국 손해보는 장사를 한다는 것입니다[왜냐하면 다른 신이 존재한다면 기독교의 신도 존재하므로 지옥도 존재하게 됩니다].

만일 니체처럼 강하게 신이 죽었다고 결론 내려버리면, 신의 존재확률은 0이되고, 파스칼의 확률론도 더이상 위력을 발휘하지 못하게 됩니다.

그러나, 잘 아시는 바와 같이 은 고교 수학에서 배우는 부정으로서 정할수 없고, 알 수 없는 값이 됩니다.

그래서 죽은 니체의 현재 상태는 지옥도 천당도 아닌
불확정성원리의 지배를 받고 있다는 결론이 내려지게 됩니다.-_-;;;

재미있는 논리이지만, 한편으로는 그 신을 믿을지 말지를 결정함에있어 수학의 확률을 도입한 파스칼의 합리성에 혀를 내두르게 됩니다.

아울러 파스칼 논리의 증명이 0(zero)와 의 개념이 수학에 도입되고 부정의 개념이 확립된 후에나 가능했다라는 점은 명약관화[明若觀火]합니다.

파스칼 이후 가우스(1777~1855)가 신의 존재 자체를 무한으로 규정하면서 "무한은 신이다. 이 신을 문제 삼는 것은 위험하다." 라고 주장하고, 니체(1844~1900)가 짜라투스트라의 입을 통해서 “만일 신이 존재하는 것이라면 인간은 기어이 신이 되고 말 것이다. 그러므로 신은 있을 수 없다"라고 신의 존재를 부정했지만, 칸토르(1845~1918)는 무한이 신이라면 인간은 이 신의 정체를 밝히지 않을 수는 없을 것이라고 믿었습니다.

칸토르의 주장대로 파스칼의 도박의 기대값을 추정하기 위해 수학에서 무한의 존재를 유한의 확률로 확립하게 되면, 철학은 세계를 인식의 대상으로 삼게 되고, 고대인이 가진 비존재의 개념이나 존재의 한계를 그으면서 생각하던 무한 공간관과는 달리 무한을 존재로서 받아들이게 되고 "신은 존재하지만(즉, 존재확률이 0이 아니라는 의미) 측정할 수 없는 불확정성의 유한 집합의 공간관"을 만들 수 있게 되는 것입니다.
Posted by sehee

알면 알수록 더 몰라간다.

그 말이 정말 이해가 안 됐다. 어떻게 알아가는데 더 모를 수가 있는걸까.

언젠가 한 교수님이 그랬다. "학부생보다 석사차가 모르는게 더 많다. 석사차 학생보다 박사차 학생이 더 모른다. 교수가 되면? 아무것도 모른다. 아마 여러분(학부생)도 과외나, 아는 동생들과 대화를 하다보면 고등학생들이 나보다 더 아는것 같다는 생각을 했던 적이 있을지도 모르겠다."

도대체 어떻게 그럴수가 있을까.

아주 사소한 사실이라도 하나를 더 알면 그 많은 더 알아야 하는게 아닌가.

아래 그림으로 도식화해보면

사용자 삽입 이미지

 노란색 원은 아는, 지식의 총량이다. 그렇다면 정의에 의해 하늘색 부분은 모르는 것(지식)의 총량이다. 도식화한 것에서 볼 수 있듯, 계산의 편의를 위해 사각형은 한변이 x인 정사각형이다. 또 r<R 이다.

 간단히 계산해보면,

 시간 t가 흐르기 전에 모르는 양은, (x^2)-π(r^2) 이며,

 시간 t가 흐른 후에는 (x^2)-π(R^2) 이다.

 직관적으로 알 수 있지만, 역시 대소 비교를 위해 앞의 것에서 뒤의 것을 빼 보면,

 곧  {(x^2)-π(r^2)} - {(x^2)-π(R^2)} = π{(r^2)(R^2)} 이고,

 정의(r<R)에 의해, 주어진 식은 0보다 작다. 곧, 시간 t 가 흐른 후의 모르는 것(지식)의 총량은 지식이 늘어남에 따라 (r → R) 줄어든다.

 곧  {(x^2)-π(r^2)} - {(x^2)-π(R^2)} = π{(r^2)(R^2)} <0 으로,

   {(x^2)-π(r^2)} > {(x^2)-π(R^2)} 이다.


하지만 다시 한번 생각해보자.


위의 도식에서는, 우리는 존재하는 모든 지식의 총량을 미리 제한했다. x라는 변을 가진 정사각형으로. 만약 그렇지 않다면? 존재하는 모든 지식은 무한대, 혹은 그 제한값을 알 수 없는 광대한 것이라면?

사용자 삽입 이미지
 
그러면 위와 같은 그림을 그릴 수 있게 된다. 우리는 지식의 한계를 알 수 없다. (혹은 없다.)
때문에 전체 지식의 총량, 따위는 계산할 수 없다. 무한대로 놓아도 무방하다.
그러면 우리가 아는 지식만 존재한다.
시간 t가 흐름에 따라 우리의 지식은 작은 (노란) 원에서 큰 (파란) 원으로 변화한다. 두 원은 각각 r'과 R'을 반지름으로 갖는 원이다. (r' < R')
그러면 우리는 우리가 가진 지식의 한계에 접하는 미지의 영역만을 '모르게' 된다. 그 너머에 무엇이 있는지는 확인할 수 없으니. 때문에 이번에 '모르는' 부분은 '넓이'가 아니라 '길이'가 된다. 원주.
 작은 원의 경우에 모르는 부분은 2πr' 이며, 큰 원의 경우에 모르는 부분은 2πR' 이다. 크기 비교를 위해 앞의 식에서 뒤의 식을 빼면, 2πr' - 2πR' = 2π(r' - R') 이고, 정의에 의해 r' < R' 이므로 주어진 식은 0보다 작다. 결과적으로,
 
 2πr' < 2πR'
 
을 얻게 된다.
 
∴ 알면 알수록 몰라간다.

요즘 드는 생각... 알면 알수록 모르는게 더 많아진다.
아는 건 잊어가고... 그나마 아는건 제대로 알고 있는 걸까? 하는 생각도...
Posted by sehee
◀ PREV : [1] : [2] : [3] : [4] : [5] : ... [8] : NEXT ▶

BLOG main image
Stay Hungry. Stay Foolish. 현실에 안주하지 않고 끊임없이 새로운 것을 갈구하며, 교만하지 않고 항상 겸손하자. by sehee

공지사항

카테고리

분류 전체보기 (77)
Log (38)
Thinking (7)
Book (5)
Movie (0)
Music (3)
It's cool (5)
Useful Info. (2)
Travel (0)
Biz-Trip (0)
Programming (11)
Project (6)

최근에 받은 트랙백

Total : 25,110
Today : 8 Yesterday : 3