<?xml version="1.0" encoding="UTF-8" ?>
<feed xmlns="http://www.w3.org/2005/Atom">
   <title type="text">Textyle</title>
      <updated>2010-09-10T04:12:48+09:00</updated>
   <id>http://www.textyle.kr/?module=rss&amp;act=atom</id>
   <link rel="alternate" type="text/html" hreflang="ko" href="http://enamu.textyle.kr/"/>
   <link rel="self" type="application/atom+xml" href="http://www.textyle.kr/?module=rss&amp;act=atom"/>
   <generator uri="http://www.xpressengine.com/" version="1.4.3.1">XpressEngine</generator>
   <entry>
      <title>신차 교환기 - 신차 산 후 결함발견시 교환 받는 방법(?)</title>
      <id>http://www.textyle.kr/2107</id>
      <published>2010-09-09T17:11:18+09:00</published>
      <updated>2010-09-09T17:12:30+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.textyle.kr/2107"/>
      <link rel="replies" type="text/html" href="http://www.textyle.kr/2107#comment"/>
      <author>
         <name>Aslan</name>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;어제 SBS 뉴스추적에서 신차를 구입한 후 얼마 되지 않아 중대한 결함이 생겨서 고생하는 피해자들에 대한 내용이 방영됐다. 그 내용 중에는 국내 자동차 회사들의 비양심적인 면과 무책임함에 대해 단적으로 엿볼수 있는 부분도 있었다. 무엇보다도 중요한 것은 그런 클레임에 대하는 절차를 잘 모르는 일반 구매자들이 당할 수 밖에 없는 억울함이 다시 내 옛날 기억을 되살리게 만들었다.&lt;/p&gt;&lt;p/&gt;&amp;nbsp;사실 나도 2006년 12월에 어제 그 방송속의 피해자들과 똑같은 상황에 처했던 피해자 중 한명이었다. 국내 자동차 회사 중 한 회사의 자동차를 2006년 12월에 구입했고 당시 구입가격은 총 3500만원! 내 힘으로 구매했던 물건 중에 가장 비싼 물건이었다..ㅋㅋ 아마 어제 방송에 나왔던 차종으로 비교해 보면 기아자동차의 K7급 정도 되는 자동차였다. 일주일을 기다려서 받은 차에 선팅 및 간단한 튜닝을 하고 3일째 되는 날 외출을 해서 한참 도로를 달리던 도중 갑자기 핸들이 잠기고 브레이크가 작동을 안해서 놀란 마음에 계기판을 봤더니 시동이 꺼져있는 것이 아닌가? 당시에는 너무 황당해서 아무런 생각이 안났지만 일단 도로 한 가운데 있었기 때문에 얼른 차를 도로 옆으로 주차를 하고 영업사원에게 전화를 했다. 주행 중 시동이 꺼졌다고 했더니 &quot;그럴리가요?&quot;라고 하며 일단 긴급출동반을 보내주겠다고 해서 30분을 기다려 결국 출고된지 3일만에 &amp;nbsp;사업소에 입고가 되었다. 주말이라 월요일까지 기다렸다가 사업소로 부터 들은 말은 어제 방송에 나왔던 것 처럼 자동차의 전자제어 장치인 ECU에 문제가 있었다는 얘기. 그래서 불량 아니냐고 했더니 이전 ECU는 16bit였는데 이 차부터는 32bit로 업그레이드가 되었는데 ECU라는게 너무 Hightech 정밀 기계라 가끔 문제가 있다고 교체 했으니 아무문제가 없을 거라고 해서 찜찜하지만 괜찮다니 알겠다고 하고 차를 받아서 나왔다.&lt;/p&gt;&lt;p/&gt;&amp;nbsp;그런데 다음날 또 다시 시동이 주행 중 시동이 꺼져버린게 아닌가? 이번에는 뒤에서 달려오던 덤프트럭이 놀라 급정지를 할 정도로 갑자기 시동이 꺼져버렸다. 너무 놀라서 이번에는 담당 영업소 직원 및 수리 담당 책임자에게 전화로 언성을 높였다. 결국 다시 사업소에 입고를 했고 이번에는 완벽하게 정비하겠다고 하여 일주일을 시간을 달라고 했었다. &lt;/p&gt;&lt;p/&gt;이 때 갑자기 내 머리속에 드는 생각이 이 차 자체가 문제가 있을 것이라 생각이 들어 표정관리를 하며 &quot;네, 알겠습니다. 대신 이번에 수리를 해서도 문제가 생긴다면 저는 교환을 요구할겁니다&quot; 라고 양쪽에 선언을 했었다. 아마 지금 소비자 법에는 동일한 문제로 2회 이상 문제가 생겼을 경우에는 교환이 된다고 되어있을 것이다. 하지만 이를 지키는 국내 자동차 제조사는 없다. 전문적인 말들로 이런 핑계 저런 핑계를 대며 소비자를 우롱만 할뿐.. &lt;/p&gt;&lt;p/&gt;&amp;nbsp;수리가 완료 됐다는 연락이 와서 가봤더니 이번에는 ECU와 통신을 하는 네트워크도 전체 다 교환을 했다는 얘기를 들었다. 나는 다행히도 업무상 국내 모자동차 연구소에서 한달동안 연구소 직원들과 자동차 기술에 대해 업무를 한 적이 있기 때문에 &amp;nbsp;정비 직원들이 하는 얘기를 어느정도는 알아들을 수 있었기 때문에 그 때 직원들이 하는 얘기에 질문도 할 수 있었다. 그런데 왠지 석연치 않은 느낌이 계속 들어서 질문을 여러번 하다가 다시 한번 &amp;nbsp;&quot;이번에도 동일한 문제가 생기면 교환할겁니다&quot;라는 말을 남기고 차를 받아서 나왔다.&amp;nbsp;&lt;/p&gt;&lt;p/&gt;그러니 결국 또 동일한 증상이 발생해 버렸다. 그래서 이번에는 내 자동차를 판매한 영업사원에게 동일한 문제가 또 발생했으니 교환을 해달라고 얘기를 하기 위해 영업소로 찾아갔다. 그러나 영업사원 입에서 나오는 말은 자기는 어떻게 할 수 없다 규정상 판매 이후의 책임은 서비스에서 담당한다라는 말만 반복했다. 그래서 그 영업소에서 결국 언성이 높아졌고 영업소장까지 불러내서 교환을 해달라고 강력하게 요청을 해봤으나 교육받은대로 앵무새 같은 기계적 답변만..&lt;/p&gt;&lt;p/&gt;그럼에도 불구하고 결론적으로 나는 교환을 받았다. 그 방법을 지금부터 소개한다.&lt;/p&gt;&lt;p/&gt;&amp;nbsp;일단 국내 자동차 판매 구조는 영업에서 판매를 소비자에게 하면 소비자가 인수한날 부터 번호판을 달때까지는 영업에게 책임이 있다. 이 책임은 차가 출고되고 임시번호판에서 확정된 번호판을 달때까지 유예되는데 보통의 경우 번호판을 출고 당일날 달아주기 때문에 영업은 거의 책임지는 기간이 없다고 보면 무방. 그래서 번호판을 달고 1달이내에 동일 증상 2회 이상이면 교환의 조건이 되는데 이 경우에도 자동차 회사는 안 해주기 위해 안간힘을 쓴다.&lt;/p&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;/&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&gt;&amp;lt;/iframe&gt;&lt;/div&gt;&lt;p/&gt;&amp;nbsp;내 경우 영업사원으로부터 약간의 팁을 받았는데 그 내용인 즉, &lt;/p&gt;&lt;p/&gt;이 문제는 영업소장, 고객센터 책임자, 해당 서비스 센터 책임자 3명의 합의가 이루어지면 교환이 된다는 것. 아마 대부분의 피해자들은 이 사실을 모르기 때문에 핑퐁 게임에 허덕이다가 포기하게 될 것인데, 일단 첫번째로 영업소장에게 엄포를 놓던 어떤 방법을 통해서라도 서비스쪽에서 문제가 있다면 교환을 해주겠다는 약속을 받아야 한다. 이 문제는 3단계 중 가장 쉽다.(ㅠㅠ) 그리고 두번째, 고객센터를 찾아가야 한다. 고객센터는 자동차 회사마다 본부의 위치가 다르기 때문에 이 정보는 영업사원에게 닥달을 해서 알아내라고 해서 책임자 이름까지 알고 찾아가서 면담을 해야한다. 그리고 역시 교환을 요청하고 이 문제를 서비스쪽에서 문제가 있다라고 하면 교환을 해달라라고 강하게 일방적 선언을 하고 나와야 한다. 확답을 못듣는데 이 단계를 왜 해야하냐고 의아해 할 수 있지만 보통의 경우 고객센터에 전화로 컴플레인하면 직급이 낮은 의사결정권이 전혀 없는 사람이 월급쟁이의 사명감으로 자기선에서 막는 경우가 100%라서 최고 책임자가 나의 문제를 모르는 경우가 많기 때문에 이를 알리고 공론화 해야하는 필요성 때문에 반드시 해야한다. 그리고 마지막 해당 서비스 사업소 정비소장 내지 센터장과의 면담이 결정적.. 분명 이 자리에서 정비소장은 차가 문제가 없으니 타도 된다라는 말과 죄송하다는 말로만 일관한다. 그래서 내 경우에는 그럼 당신이 이 차를 한달동안 운행하고 그래도 문제가 없다면 내가 타겠다 라고 했더니 거기서 멈칫 하면서 그럼 좋다. 교환해주겠다라는 말이 나왔다. (보통 언론에 까발기겠다, 또는 인터넷에 올리겠다라는 협박을 하면 되겠지라고 생각할 수 있지만 아쉽게도 전혀 효력이 없다. 정말 눈하나 깜박이지 않는다. 차라리 조용히 있을테니 내 문제만 해결해달라고 하는게 더 효과적이다. 아마 그래서 해결리 됐는지도 모르겠다.)&lt;/p&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;/&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&gt;&amp;lt;/iframe&gt;&lt;/div&gt;&lt;p/&gt;&amp;nbsp;그 후에 이 사실을 영업소장에게 다시 확인하고 영업소장이 지역 영업대표와 정비소장과 얘기한 후 나는 일주일 후에 신차를 받을 수 있었다. 신차를 다시 건네면서 영업소장이 나에게 하는 말은 자기도 바꿔주고 싶지만 최종확정은 이렇게 3개 파트에서 합의가 이루어 져야 한다고...&lt;/p&gt;&lt;p/&gt;자기도 힘이 없다면서.. 이해를 호소했다.&amp;nbsp;&lt;/p&gt;&lt;p/&gt;&amp;nbsp;더욱 황당한 사실은 문제가 있었던 그차는 다 뜯어서 수리한 후에 5% 할인해서 다시 팔았다는 거... 결국 그 문제 있던 차를 누군가는 사서 타고 다니고 있다는거 아닌가? 이게 국내 자동차 제조사들이 소비자에게 하고 있는 현실인 것이다.&lt;/p&gt;&lt;p/&gt;&amp;nbsp;물론 이 방법대로 해도 문제있는 자동차를 신차로 교환 받기란 하늘의 별따기 일 것이다. 내 경우는 정말 운이 좋았던 것이라고 밖에는 생각할 수 없지만, 내가 3년이 지난 지금 이 얘기를 밝히는 것은 이와 동일한 문제로 억울함을 어디다가 호소도 못하는 많은 소비자들에게 조금이나마 방법적으로 순서라도 알고 컴플레인을 할 수 있었으면 하는 차원이고 또 당시에 나에게 차를 팔았던 영업사원이나 영업소장 모두 그 업계를 떠났기 때문에 이 글을 밝히더라도 조금 미안해지는 사람이 없기 때문(?)이랄까? ㅋㅋ&lt;/p&gt;&lt;p/&gt;&amp;nbsp;개인이 소유할 수 있는 재산 중에 집 다음으로 많은 돈을 지불해야 구입할 수 있는 자동차가 구입할 때 부터 중대한 문제를 안고 있다면 정말 속이 상하다. 이럴때 이런 문제로 해결책을 못 찾고 있을 많은 피해자들에게 이 사례가 조금이나마 문제를 해결하는데 도움이 되었으면 좋겠다.&lt;/p&gt;&lt;p/&gt;&amp;nbsp;(참고로 위의 내용은 제 개인적인 특수한 상황에 대한 해결 방법이었다라는 것을 다시 한번 강조합니다.) &amp;nbsp;&lt;/p&gt;&lt;/div&gt;</content>
                  <category term="자동차"/>
            
   </entry>
   <entry>
      <title>Server의 여러가지 유형</title>
      <id>http://www.textyle.kr/1805</id>
      <published>2010-09-01T11:00:23+09:00</published>
      <updated>2010-09-08T14:21:58+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.textyle.kr/1805"/>
      <link rel="replies" type="text/html" href="http://www.textyle.kr/1805#comment"/>
      <author>
         <name>우와신난다</name>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;DIV class=&quot;titleWrap&quot; /&gt;
&lt;H2/&gt;&lt;A class=&quot;entry-title&quot; title=&quot;인터넷 서비스(TCP 기반)를 위한 서버 유형 정리&quot; href=&quot;/entry/internet-tcp-server-styles&quot; rel=&quot;bookmark&quot; /&gt;인터넷 서비스(TCP 기반)를 위한 서버 유형 정리&lt;/A&gt;&lt;/H2&gt;&lt;/DIV&gt;&lt;!--//titleWrap--&gt;
&lt;DIV class=&quot;article entry-content&quot;/&gt;
&lt;DL/&gt;
&lt;DT/&gt;&lt;/DT&gt;
&lt;DD/&gt;1. &lt;A href=&quot;#H_1&quot;/&gt;서문&lt;/A&gt;&lt;/DD&gt;&lt;BR/&gt;
&lt;DT/&gt;&lt;/DT&gt;
&lt;DD/&gt;2. &lt;A href=&quot;#H_2&quot;/&gt;Local Scheduler / System Scheduler&lt;/A&gt;&lt;/DD&gt;&lt;BR/&gt;
&lt;DT/&gt;&lt;/DT&gt;
&lt;DD/&gt;3. &lt;A href=&quot;#H_3&quot;/&gt;Symmetric Job Unit / Asymmetric Job Unit&lt;/A&gt;&lt;/DD&gt;&lt;BR/&gt;
&lt;DT/&gt;&lt;/DT&gt;
&lt;DD/&gt;4. &lt;A href=&quot;#H_4&quot;/&gt;Process / Thread (per client)&lt;/A&gt;&lt;/DD&gt;&lt;BR/&gt;
&lt;DT/&gt;&lt;/DT&gt;
&lt;DD/&gt;5. &lt;A href=&quot;#H_5&quot;/&gt;Pre-spawned / Post-spawn (per connection-request)&lt;/A&gt;&lt;/DD&gt;&lt;BR/&gt;
&lt;DT/&gt;&lt;/DT&gt;
&lt;DD/&gt;6. &lt;A href=&quot;#H_6&quot;/&gt;Reuse / One-time use (job unit life cycle)&lt;/A&gt;&lt;/DD&gt;&lt;BR/&gt;
&lt;DT/&gt;&lt;/DT&gt;
&lt;DD/&gt;7. &lt;A href=&quot;#H_7&quot;/&gt;Configurable / Fixed job&lt;/A&gt;&lt;/DD&gt;&lt;BR/&gt;
&lt;DT/&gt;&lt;/DT&gt;
&lt;DD/&gt;8. &lt;A href=&quot;#H_8&quot;/&gt;Single port listening / Multiple ports listening&lt;/A&gt;&lt;/DD&gt;&lt;BR/&gt;
&lt;DT/&gt;&lt;/DT&gt;
&lt;DD/&gt;9. &lt;A href=&quot;#H_9&quot;/&gt;Level detected triggering / Edge detected triggering&lt;/A&gt;&lt;/DD&gt;&lt;BR/&gt;
&lt;DT/&gt;&lt;/DT&gt;
&lt;DD/&gt;10. &lt;A href=&quot;#H_10&quot;/&gt;Asynchronous / Synchronous Handling&lt;/A&gt;&lt;/DD&gt;&lt;BR/&gt;
&lt;DT/&gt;&lt;/DT&gt;&lt;/DL&gt;&lt;BR/&gt;&lt;BR/&gt;&lt;BR/&gt;
&lt;H2/&gt;1. 서문&lt;/H2&gt;&lt;BR/&gt;&lt;BR/&gt;서버를 설계할 때 다음 같은 요소를 가지고 선택하게 된다.&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;OL/&gt;&lt;BR/&gt;
&lt;LI/&gt;local-scheduler / system-scheduler (non-block socket handler)&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;symmetric / asymmetric job unit&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;process / thread (per client)&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;pre-spawn / post-spawn (per connection request)&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;configurable / fixed job (job unit modifiablity)&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;reuse / one-time use (job unit life cycle)&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;single port listening / multiple ports listening &lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;edge detected triggering / level detected triggering&lt;BR/&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;이들은 대개 서버 설계 초기에 주로 선택하나, 때로는 중간에 그 모델을 바꾸어 설계할 수도 있다. 그러나 어떤 것들은 임기응변식으로 서버 설계 변경이 가능하나, 어떤 변경은 처음부터 완전히 다시 작성해야하는 경우가 생기기도한다. 서버를 설계할 때 내외적인 상황에 대하여 고려해야할 사실관계들을 살펴보고 적절한 선택을 위해 정리해보고자 한다. 위에서 나열한 요소들은 하나의 서버를 설계할 때 부분적으로 선택되어지므로, &lt;STRONG/&gt;어떤 상황에 대한 서버를 설계할 것인지&lt;/STRONG&gt;를 충분히 고려하지 않으면, 설계 변경시 상당한 충격이 있을 것이다.&lt;BR/&gt;&lt;/P&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;H2/&gt;2. Local Scheduler / System Scheduler&lt;/H2&gt;&lt;BR/&gt;&lt;BR/&gt;Non-block I/O, Thread Pool 개념을 사용할 것인가? &lt;BR/&gt;&lt;BR/&gt;Process, Thread 전담형으로 만들 것인가? &lt;BR/&gt;&lt;BR/&gt;&lt;BR/&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;선택의 동기&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;OL/&gt;&lt;BR/&gt;
&lt;LI/&gt;흔히 non-block socket을 쓸 것이냐, block socket을 쓸 것이냐로 구분하기 쉬운 것을 job scheduler(작업 스케쥴러) 혹은 task switching 입장에서 구분해보았다. 그 만큼 non-block I/O를 통해 처리하는 서버에서는 작업 스케쥴하는 비용이 크게 고려되어야한다는 것이며, 프로세스나 쓰레드의 스케쥴링에 들어가는 시간보다 클라이언트 요구를 처리하기 위해 들어가는 시간에 집중하도록 설계하는 것을 의미한다.&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;시스템 스케쥴러를 사용한다는 것은 여러접속의 요구 처리를 프로세스 혹은 쓰레드 스케쥴링에 넘겨 처리하겠다는 것이다.&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;스케쥴러에 들어가는 비용을 아까워하는 경우에 Local Scheduler(로컬 스케쥴러)를 선택하게 된다. 예를 들어 데이터의 양도 많고 동시 접속도 많은 경우를 생각해보자, 동시에 1000개 이상의 접속이 생기고 이것들을 프로세스 1000개로 운영하는 것보다 2 개정도의 프로세스가 500개씩 나누어 처리하면, OS의 스케쥴에 해당하는 비용을 크게 줄일 수 있을 것이다. 여기에서 500개의 접속을 하나의 프로세스에서 효과적으로 처리하기 위하여 로컬 스케쥴러라는 말을 도입하였다.&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;로컬 스케쥴러라는 것은 User level thread 수준의 복잡도를 요구하는 것이 아니며, non-block I/O를 처리하거나 Thread-pool을 도입하여 &lt;STRONG/&gt;소켓당 State machine을 잘 운용&lt;/STRONG&gt;하는 수준의 스케쥴러를 말한다.&lt;BR/&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;이점 및 주의점&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;OL/&gt;&lt;BR/&gt;
&lt;LI/&gt;Local scheduler는 하나의 프로세스에서 작업 분배를 논리적으로 구분한 것일 뿐, OS가 보기에는 하나의 프로세스에 불과하다. 즉, 간단한 User-level thread라고 생각해도 좋을 정도이다. 따라서, system call을 수반하는 무거운 context switching을 막을 수 있으며, 작업들간의 분배가 상당히 가벼운 것에 그 이점이 있다.&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;주의할 것은 non-block 소켓을 다룰때는 특히 대량의 접속에 대한 처리가 있을 때, 프로세스당 열 수 있는 최대 디스크립터 수에 도달할 가능성이 많다. 이 경우 똑같은 일을 하는 프로세스가 listen port를 공유하여 경쟁적으로 클라이언트를 접수하는 pre-forked 방식 서버를 사용하여야한다.&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;모든 작업은 하나의 프로세스내에 남기 때문에 쓰레드 프로그래밍과 같은 (함수 재진입 문제 등) 수준의 주의를 요한다.&lt;BR/&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;구현에 따른 고려사항&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;BR/&gt;크게 영향을 받는 요인은 프로세스당 최대 열 수 있는 디스크립터 수와 CPU의 개수이다. 후자에 대해서는 CPU 개수의 두 배정도에서 작업전환 비용을 절감하는 이점을 최대화 시키는 것이 경험적으로 알려져 있다. 즉, non-block I/O를 처리하는 쓰레드 풀안의 쓰레드 개수는 1 CPU machine에서 두 개정도가 적당하며, 그 이상 늘여도 성능향상이 월등히 좋아지지는 않는다는 것이다.&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;H2/&gt;3. Symmetric Job Unit / Asymmetric Job Unit&lt;/H2&gt;&lt;BR/&gt;&lt;BR/&gt;생성되는 프로세스/쓰레드가 모두 같은 일을 하는가? &lt;BR/&gt;&lt;BR/&gt;생성되는 프로세스/쓰레드 마다 역할이 분배되어 있는가? &lt;BR/&gt;&lt;BR/&gt;&lt;BR/&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;선택의 동기&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;OL/&gt;&lt;BR/&gt;
&lt;LI/&gt;프로세스 혹은 쓰레드가 다수 만들어 질 때, 이들은 모두 같은 일을 하거나(대칭적 작업단위) 상호 협조(비대칭 작업단위)를 하는 모델로 만들어진다.&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;예를 들면, HTTP Proxy 설계에 하나의 접속건에 대하여 하나의 쓰레드가 만들어진다면, 이 쓰레드 하나가 클라이언트를 요구를 파싱하고 접속해야할 서버에 접속하며, 서버의 응답을 다시 릴레이하는 일련의 과정을 전담하도록 설계되거나, 두 개정도의 쓰레드로 나누어 하나는 클라이언트와 접속을 담당하고 다른 하나는 서버쪽 접속을 담당하는 형태로 설계될 수 있다. 그 외에 주기적으로 가비지 콜렉팅을 하는 쓰레드도 만들수 있고, 로그를 분리하기 위한 쓰레드도 만들어 질 수 있다.&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;대칭적인 서버는 모든 프로세스 혹은 쓰레드가 동일한 일을 하는 작업 단위로 만들어져 접속된 클라이언트의 요구사항을 전담하여 처리한다.&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;하나의 처리가 짧은 응답시간을 갖지 않는 경우 처리를 여러 단계로 나누어 각 단계마다 복잡할 수록 여러 프로세스 혹은 쓰레드로 나누어 처리시킬 수 있다.이는 경험적인 프로세스 수 조정 과정을 통해 병목이 생길 수 있는 단계에 여러 프로세스를 둘 수 있는 우아함을 지원하게 된다.&lt;BR/&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;이점 및 주의점&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;OL/&gt;&lt;BR/&gt;
&lt;LI/&gt;작업단위 쪼개어 만들어지므로 설계와 구현에서 고립화가 쉽다. 재사용이 가능하므로 쓰레드나 프로세스 수가 경제적으로 생성되며, 그 라이프 사이클도 상당히 경제적이다. &lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;작업단위가 추상화되면, 업그레이드나 작업단계 추가등이 상당히 명료하다.&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;요청이 여러 작업단위를 뛰어 다니므로 중간에 분실될 우려가 있다. &lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;단순한 요청사항인 경우 굳이 작업단위를 나누게 되면 오히려 복잡한 설계가 될 수 있다.&lt;BR/&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;H2/&gt;4. Process / Thread (per client)&lt;/H2&gt;&lt;BR/&gt;&lt;BR/&gt;하나의 접속에 대하여 한 프로세스를 만들어 처리할 것인가? &lt;BR/&gt;&lt;BR/&gt;하나의 쓰레드를 만들어 처리할 것인가? &lt;BR/&gt;&lt;BR/&gt;&lt;BR/&gt;작업개체를 프로세스로 할 것인가? &lt;BR/&gt;&lt;BR/&gt;작업개체를 쓰레드로 할 것인가?&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;선택의 동기&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;BR/&gt;이 문제는 프로세스를 생성하는데 드는 비용이 많다는 것에 기초한다. 전통적으로 fork를 하는데 들어가는 비용이 크기 때문에, vfork라는 개념도 생기며, 뒤에서 보게될 prefork라는 개념도 생기게 된다. 일이 발생했을 때, 무거운 시스템콜을 될 수 있으면 줄이려고 대신 thread를 택할 수 있다.&lt;BR/&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;쓰레드의 이점과 주의점&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;OL/&gt;&lt;BR/&gt;
&lt;LI/&gt;이점은 모든 쓰레드가 메모리를 공유하면서 생기는 클라이언트간 자료공유가 쉬운 것에 있다. 또한 많은 OS에서 쓰레드 생성비용이 프로세스보다 작다.&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;문제는 하나의 쓰레드는 &lt;STRONG/&gt;완전무결&lt;/STRONG&gt; 해야하는데 있다. 즉, &lt;STRONG/&gt;리소스 (메모리, 디스크립터 등)가 절대 새지 않아야하며, 쓰레드 자체가 치명적인 오류를 일으켜 프로세스 전체에 영향을 줘서는 안되는데 있다.&lt;/STRONG&gt; 반면, 접속이 해제됨과 동시에 프로세스가 종료되는 경우 리소스는 자동으로 해제되므로 쓰레드 기반보다는 견고하다.&lt;BR/&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;구현에 따른 고려사항&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;OL/&gt;&lt;BR/&gt;
&lt;LI/&gt;리눅스의 경우 쓰레드의 생성이나 프로세스의 생성이 그다지 비용차이가 많지 않다. 즉, 리눅스의 쓰레드는 좀 무거운 편이다. 따라서 fork에 들어가는 비용을 고려하는 것만으로 쓰레드를 선택하지는 않는다.&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;쓰레드의 경우 User level 쓰레드와 Kernel level 쓰레드가 있다. 이 경우 User level일 때의 고려사항은 자칫 하나의 쓰레드에서 block 상황에 빠지게 되어 프로세스가 멈추게 되는 상황이다. &lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;쓰레드의 경우 하나의 쓰레드가 차지하는 stack의 크기가 있으므로, 쓰레드 생성시 적절한 스택의 크기를 정하는 문제가 발생한다. 스택의 크기에 따라서 생성되는 쓰레드 최대 수가 달라지기 때문이다.&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;쓰레드의 경우 하나의 프로세스가 열 수 있는 최대 프로세스 개수에 제한이 있고 그것에 도달하는 경우는 어쩔 수 없는 한계에 도달한 것이라 생각하고 변경해야하는 경우가 있다.&lt;BR/&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;H2/&gt;5. Pre-spawned / Post-spawn (per connection-request)&lt;/H2&gt;&lt;BR/&gt;&lt;BR/&gt;connection 요구가 있을 때, 새로운 작업개체를 만들고 수신하여 처리결과를 전송할 것인가? &lt;BR/&gt;&lt;BR/&gt;미리 만들어진 작업개체가 connection 요구를 accept하고 수신하여 처리결과를 전송할 것인가? &lt;BR/&gt;&lt;BR/&gt;&lt;BR/&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;선택의 동기&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;BR/&gt;Process 생성에 들어가는 비용이 많이 들기 때문에, 사전에 Process를 준비하여 빠른 응답을 줄 수 있도록한다.&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;Pre-spawned의 이점과 주의점&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;OL/&gt;&lt;BR/&gt;
&lt;LI/&gt;접속을 전담하는 형태로 작성되며, 대개 전담하는 모델이 이미 접속된 소켓에 대하여 하는 것과는 달리, 접속요구를 accept하는 것부터 전담하게 된다.&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;동시에 두개의 port를 listen하는 경우 accept하기전 select를 사용하고, 이 select에 참여하는 작업개체(Process, thread)를 하나로 한정하기 위해 semaphore나 mutex 등을 둔다. 이는 accept 경쟁에 실패한 작업개체들이 한 포트의 accept에 멈춰있어 다른 포트에 accept할 기회가 상실되는 것을 막기 위함이다.&lt;BR/&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;H2/&gt;6. Reuse / One-time use (job unit life cycle)&lt;/H2&gt;&lt;BR/&gt;&lt;BR/&gt;접속을 전담하는 작업개체가 접속이 종료되면 같이 종료되나? &lt;BR/&gt;&lt;BR/&gt;접속을 전담하는 작업개체가 접속이 종료되면 다른 접속을 받기 위해 대기하나? &lt;BR/&gt;&lt;BR/&gt;몇번의 접속을 전담하고나면 종료되나? &lt;BR/&gt;&lt;BR/&gt;&lt;BR/&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;선택의 동기&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;OL/&gt;&lt;BR/&gt;
&lt;LI/&gt;작업개체의 생성에 들어가는 비용을 줄이기 위해 재사용하도록 한다. 주로 Pre-spawned(Pre-forked) 방식에서 사용된다.&lt;BR/&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;reuse 모델에서의 이점과 주의점&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;OL/&gt;&lt;BR/&gt;
&lt;LI/&gt;이전 접속의 데이터가 다음 접속에 영향을 주어서는 안된다.&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;한 클라이언트의 접속/응답 시간이 작은 경우에는 효과적이나, 그렇지 않은 경우에는 고려하기 어렵다.&lt;BR/&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;H2/&gt;7. Configurable / Fixed job&lt;/H2&gt;&lt;BR/&gt;&lt;BR/&gt;접속을 받아 실제 응답을 주는 것은 고정되어 있나? &lt;BR/&gt;&lt;BR/&gt;접속을 받아 실제 응답을 주는 작업이 바이너리 릴리즈 후에 추가되거나 수정될 수 있는가? &lt;BR/&gt;&lt;BR/&gt;&lt;BR/&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;선택의 동기&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;BR/&gt;서비스 모델이 확장성은 고려되지 않는 경우 모든 작업은 컴파일되어 릴리즈 되지만, 버전업이 잦거나 접속이 종료되지 않은 상황으로 hotfix를 해야하는 경우를 고려하면, 선택해야한다.&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;이점과 주의점&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;OL/&gt;&lt;BR/&gt;
&lt;LI/&gt;외부 모듈이 실행되는 형태로 작성되므로, 보안상 허점이 발견될 수 있다.&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;안정성이 해결된 바이너리라는 확인작업 없이 hotfix하면, 기존의 서비스도 중지될 수 있다.&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;외부 모듈을 통해 인증을 거칠 수 있다.&lt;BR/&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;구현시 주의점&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;OL/&gt;&lt;BR/&gt;
&lt;LI/&gt;구현을 inetd와 같은 방식으로 할 경우 accept후 fork/exec를 사용한다.&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;구현을 shared object 방식으로 할 경우 외부 object를 dlopen 한다.&lt;BR/&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;H2/&gt;8. Single port listening / Multiple ports listening&lt;/H2&gt;&lt;BR/&gt;&lt;BR/&gt;서비스 포트가 하나인가? &lt;BR/&gt;&lt;BR/&gt;서비스 포트가 하나 이상인가? &lt;BR/&gt;&lt;BR/&gt;&lt;BR/&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;선택의 동기&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;BR/&gt;외부에 두 개의 port를 보임으로서 다른 프로토콜 또는 다른 주소를 하나의 서비스안에서 구현한다.&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;이점과 주의점&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;OL/&gt;&lt;BR/&gt;
&lt;LI/&gt;하나의 바이너리만을 배포함으로써 서비스를 간소화시킬 수 있다. 대표적으로 inetd, apache web server&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;accept 경쟁이 일어날 경우 한쪽 port로 몰려 &quot;port 왕따 현상&quot;이 일어나지 않아야한다.&lt;BR/&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;구현 참고&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;OL/&gt;&lt;BR/&gt;
&lt;LI/&gt;서비스 구분은 getsockname을 통해서 local port를 구함으로써 알 수 있다.&lt;BR/&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;H2/&gt;9. Level detected triggering / Edge detected triggering&lt;/H2&gt;&lt;BR/&gt;&lt;BR/&gt;수신 요청 신호를 확인하여 응답할 것인가? &lt;BR/&gt;&lt;BR/&gt;요청 버퍼를 확인하여 응답할 것인가? &lt;BR/&gt;&lt;BR/&gt;&lt;BR/&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;선택의 동기&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;BR/&gt;시스템에서 제공하는 전통적인 select, poll 방식의 감지는 동시에 참여하는 descriptor 수가 많아질 경우 scan하는 비용이 많이 들어간다. 따라서, 수신요청이 있을 때 바로 처리하도록한다.&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;이점과 주의점&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;OL/&gt;&lt;BR/&gt;
&lt;LI/&gt;대량의 접속을 처리해야하는 경우 서비스를 해야할 시점을 선택하는 문제를 접속 혹은 수신 통지 서비스를 이용하므로 응답시간을 단축할 수 있다.&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;한번의 수신 통지에서 버퍼에 남겨두는 것이 없도록 모두 비워주지 않으면, 버퍼 오버플로가 발생하여 서비스가 정지할 수 있다.&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;OS에 의존하는 서비스를 이용하므로 이식성을 포기해야한다.&lt;BR/&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;H2/&gt;10. Asynchronous / Synchronous Handling&lt;/H2&gt;&lt;BR/&gt;&lt;BR/&gt;요청한 작업을 Callback함수를 통해 마무리 할 것인가? &lt;BR/&gt;&lt;BR/&gt;요청한 작업이 종료될때까지 기다릴 것인가?&lt;BR/&gt;요청한 작업이 종료되었는지 확인하여 처리할 것인가? &lt;BR/&gt;&lt;BR/&gt;&lt;BR/&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;선택의 동기&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;OL/&gt;&lt;BR/&gt;
&lt;LI/&gt;read/write 시스템콜을 사용하는 전송요청은 전송이 마무리 될때까지 대기하여 시간을 소비하게 된다. 이 대기 시간을 의미있게 사용하기 위해, 수신/전송 요청과 실제 수신 데이터 도착 / 송신 완료가 이루어지는 시점을 분리하여 그 사이에 다른 일을 하도록 한다.&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;사용자의 수신/전송 요청에 대한 결과를 확인하는 것과 요청에 대한 커널의 응답이 비동기적으로 한다.&lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;read/write 라는 하나의 명령을 사용하지 않고, asynchronous I/O 구현 Library의 request, callback 메커니즘을 사용한다.&lt;BR/&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;BR/&gt;
&lt;P/&gt;&lt;BR/&gt;&lt;/P&gt;
&lt;UL/&gt;&lt;BR/&gt;
&lt;LI/&gt;이점과 주의점&lt;BR/&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;OL/&gt;&lt;BR/&gt;
&lt;LI/&gt;전통적인 signal-base async I/O는 signal 이라는 상대적으로 무거운 시스템콜을 통하여 일어나므로 매 처리가 signal handling 상황이라는 것에 주의해야한다. &lt;BR/&gt;&lt;/LI&gt;
&lt;LI/&gt;대개 라이브러리에 의존하는 서비스이므로 이식성을 포기해야한다.&lt;BR/&gt;&lt;BR/&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;/DIV&gt;&lt;/div&gt;</content>
                  <category term="서버"/>
            <category term="tcp/ip"/>
            <category term="tcp"/>
            <category term="서버유형"/>
            
   </entry>
   <entry>
      <title>텍스타일의 세계로 오신것을 환영합니다!</title>
      <id>http://www.textyle.kr/1776</id>
      <published>2010-08-31T18:09:39+09:00</published>
      <updated>2010-08-31T18:09:39+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.textyle.kr/1776"/>
      <link rel="replies" type="text/html" href="http://www.textyle.kr/1776#comment"/>
      <author>
         <name>sol</name>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;div class=&quot;eArea xe_content xe_dr_txt&quot;/&gt;
    &lt;p/&gt;더 좋은 글쓰기를 위해 어떤 도움이 필요할까요? 더 쉬운 글쓰기를 위해서는요? 텍스타일은 &quot;더 좋은 글을 더 쉽게 쓰고싶다&quot;는 욕구로 부터 시작되었습니다. 만약 지금 여러분&amp;nbsp;곁에 좋은 글쓰기 선생님을 둘 수 없다면 텍스타일을 선택한 것은 무척 고무적인 일입니다. 텍스타일의 글쓰기 도구는 조금 특별 하거든요. ^^ 함께 만나 보시죠!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_hx&quot;/&gt;
    &lt;h3 id=&quot;h1247467217012&quot;/&gt;글감 수집기를 설치해 보세요!&lt;/h3&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_txt&quot;/&gt;
    &lt;p/&gt;좋은 글에는 항상 참조와 인용이 따릅니다. 글감 수집기는 좋은 글이&amp;nbsp;보다 많은 사람들의 글과 객관적인 사실을 참조하고 있다는 사실에 주목하였고 글을 쓰는 과정에서 이러한 작업을 보다 편리하게 할 수 있도록 도울 것입니다. &quot;글감 수집기&quot;를 여러분의 브라우징 도구에 북마크 하시면 웹 서핑 도중 참조하거나 인용하고 싶은 글을 여러분의 텍스타일에&amp;nbsp;담아둘 수 있습니다. 하지만 기억하세요. 다른 사람의 글을 수집한 다음 다시 배포할 때 저작권자가 이런 행동을 허용하고 있는지 반드시 확인해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_img&quot;/&gt;
    &lt;p/&gt;&lt;img src=&quot;./modules/textyle/sample/ko/aboutTextyle1.gif&quot; id=&quot;&quot; alt=&quot;&quot;/&gt;&lt;/p&gt;
    &lt;p class=&quot;desc&quot;/&gt;글감 수집기는 &quot;글 관리 &amp;gt; 글감보관함&quot; 페이지에서 설치할 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_img&quot;/&gt;
    &lt;p/&gt;&lt;img src=&quot;./modules/textyle/sample/ko/aboutTextyle4_2.gif&quot; id=&quot;xe_img_srl_11746&quot; alt=&quot;&quot;/&gt;&lt;/p&gt;
    &lt;p class=&quot;desc&quot;/&gt;글감 수집기가 웹 브라우저의 북마크 도구모음에 설치된 화면.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_img&quot;/&gt;
    &lt;p/&gt;&lt;img src=&quot;./modules/textyle/sample/ko/aboutTextyle2_3.gif&quot; id=&quot;xe_img_srl_11750&quot; alt=&quot;&quot;/&gt;&lt;/p&gt;
    &lt;p class=&quot;desc&quot;/&gt;웹 브라우저에 설치된 &quot;글감 수집기&quot;를 이용하여 인용구를 수집하는 장면.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_hx&quot;/&gt;
    &lt;h3 id=&quot;h1247469280842&quot;/&gt;텍스타일 에디터를 사용해 보세요!&lt;/h3&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_txt&quot;/&gt;
    &lt;p/&gt;텍스타일 에디터는 텍스타일을 다른 블로깅 도구들과 차별화 하는 가장 두드러진 특징 가운데 하나 입니다. 텍스타일 에디터는 &quot;좋은 글 쓰기&quot;를 위해 개발되었고 텍스타일 에디터를 이용해서 작성된 글은 보다 논리적이고 읽기 편하며 의미있고 검색엔진과 친해질 확률이 더 높습니다. 하지만 이 도구에 익숙하지 않은 분들을 위하여 기존에 사용하시던 익숙한 에디터를 사용할 수 있도록 고려되어 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_img&quot;/&gt;
    &lt;p/&gt;&lt;img src=&quot;./modules/textyle/sample/ko/aboutTextyle3_2.gif&quot; id=&quot;&quot; alt=&quot;&quot;/&gt;&lt;/p&gt;
    &lt;p class=&quot;desc&quot;/&gt;텍스타일 에디터를 이용하여 하나의 단락을 작성하는 화면.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_hx&quot;/&gt;
    &lt;h3 id=&quot;h1247471325766&quot;/&gt;텍스타일 에디터를 조금 더 편리하게.&lt;/h3&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_list&quot;/&gt;
    &lt;ul/&gt;
        &lt;li/&gt;&lt;span/&gt;텍스타일 에디터 열기 : 1부터 9까지 사용.&lt;/span&gt;&lt;/li&gt;
        &lt;li/&gt;&lt;span/&gt;편집 모드로 전환 : &apos;Enter&apos; 또는 &apos;더블 클릭&apos; 또는 &apos;편집&apos;을 클릭.&lt;/span&gt;&lt;/li&gt;
        &lt;li/&gt;&lt;span/&gt;단락 선택 : 선택하려는 단락을 &apos;클릭&apos; 또는 &apos;방향키&apos;를 위아래로 이동하여 선택.&lt;/span&gt;&lt;/li&gt;
        &lt;li/&gt;&lt;span/&gt;선택된 단락을 이동 : &apos;Ctrl+방향키&apos; 또는 &apos;드래그&amp;amp;드롭&apos;.&lt;/span&gt;&lt;/li&gt;
    &lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_hx&quot;/&gt;
    &lt;h3 id=&quot;h1247469866936&quot;/&gt;익숙한 에디터 사용하기.&lt;/h3&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_txt&quot;/&gt;
    &lt;p/&gt;새로운것은 언제나 불편하다는 사실을 잘 알고 있습니다. 텍스타일 에디터는 기존에 사용하던 도구들과 다른 환경을 제공하고 있기 때문에 처음에는 낮설고 불편할런지도 모릅니다. 실제로 텍스타일 에디터는 좋은 글쓰기를 위해 기존의 글쓰기 환경이 제공하던 많은 것들을 포기하고 있습니다. 풍부한 표현보다 구조적인 글쓰기에 집중할 수 있도록 유도하는 과정에서 할 수 없는 일들이 생겨나게 되었습니다. 하지만 여러분이 이 불편한 도구에 익숙해지기위해 작은 노력과 주의를 기울인다면 여러분의 글은 틀림없이 예전보다 더 좋아질 것입니다. &lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_img&quot;/&gt;
    &lt;p/&gt;&lt;img src=&quot;./modules/textyle/sample/ko/aboutTextyle5_1.gif&quot; id=&quot;xe_img_srl_11752&quot; alt=&quot;&quot;/&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_txt&quot;/&gt;
    &lt;p/&gt;여전히 텍스타일 에디터가 익숙하지 않는 분들께서는 관리자 환경의 &quot;설정 &amp;gt; 쓰기환경 설정 &amp;gt; 편집방식 설정&quot; 메뉴에서 &quot;기타 편집기&quot;를 선택 하세요. &apos;XpressEditor, FCKeditor, Xquared&apos; 와 같이 기존에 여러분들이 사용하시던 익숙한 오픈소스 에디터를 그대로 사용하실 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_hx&quot;/&gt;
    &lt;h3 id=&quot;h1247460895830&quot;/&gt;스킨 편집하기.&lt;/h3&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_txt&quot;/&gt;
    &lt;p/&gt;만약 여러분이 선택한 스킨이 컬럼 구조를 유지하고 있다면 화면의 좌우 배치를 쉽게 바꿀 수 있습니다. 모든 스킨이 이렇게 컬럼 형태를 유지하고 있는것은 아니기 때문에 손쉬운 스킨 조작 화면이 존재하는 것은 아니지만 간단하게 HTML 코드를 변경하는 것으로 가능하게 됩니다&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_img&quot;/&gt;
    &lt;p/&gt;&lt;img src=&quot;./modules/textyle/sample/ko/aboutTextyle6.gif&quot; id=&quot;xe_img_srl_11743&quot; alt=&quot;&quot;/&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_txt&quot;/&gt;
    &lt;p/&gt;&quot;디자인 &amp;gt; HTML·CSS 편집 &amp;gt; HTML 편집&quot; 화면에서 두 번째 라인 &amp;lt;div id=&quot;container&quot; class=&quot;&lt;span style=&quot;font-weight: bold; text-decoration: underline;&quot;/&gt;ce&lt;/span&gt;&quot;&amp;gt; 부분을 &amp;lt;div id=&quot;container&quot; class=&quot;&lt;span style=&quot;font-weight: bold; text-decoration: underline;&quot;/&gt;ec&lt;/span&gt;&quot;&amp;gt; 으로 변경하시면 화면의 좌우 배치가 바뀝니다. 이러한 설정은 &apos;초기화&apos; 하거나 다른 스킨을 선택했을 때 사라집니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</content>
                  <category term="textyle"/>
            <category term="텍스타일"/>
            <category term="텍스타일에디터"/>
            <category term="글감수집기"/>
            
   </entry>
   <entry>
      <title>텍스타일의 세계로 오신것을 환영합니다!</title>
      <id>http://www.textyle.kr/1757</id>
      <published>2010-08-31T18:09:03+09:00</published>
      <updated>2010-08-31T18:09:03+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.textyle.kr/1757"/>
      <link rel="replies" type="text/html" href="http://www.textyle.kr/1757#comment"/>
      <author>
         <name>행복한고니</name>
                  <uri>http://mygony.com</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;div class=&quot;eArea xe_content xe_dr_txt&quot;/&gt;
    &lt;p/&gt;더 좋은 글쓰기를 위해 어떤 도움이 필요할까요? 더 쉬운 글쓰기를 위해서는요? 텍스타일은 &quot;더 좋은 글을 더 쉽게 쓰고싶다&quot;는 욕구로 부터 시작되었습니다. 만약 지금 여러분&amp;nbsp;곁에 좋은 글쓰기 선생님을 둘 수 없다면 텍스타일을 선택한 것은 무척 고무적인 일입니다. 텍스타일의 글쓰기 도구는 조금 특별 하거든요. ^^ 함께 만나 보시죠!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_hx&quot;/&gt;
    &lt;h3 id=&quot;h1247467217012&quot;/&gt;글감 수집기를 설치해 보세요!&lt;/h3&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_txt&quot;/&gt;
    &lt;p/&gt;좋은 글에는 항상 참조와 인용이 따릅니다. 글감 수집기는 좋은 글이&amp;nbsp;보다 많은 사람들의 글과 객관적인 사실을 참조하고 있다는 사실에 주목하였고 글을 쓰는 과정에서 이러한 작업을 보다 편리하게 할 수 있도록 도울 것입니다. &quot;글감 수집기&quot;를 여러분의 브라우징 도구에 북마크 하시면 웹 서핑 도중 참조하거나 인용하고 싶은 글을 여러분의 텍스타일에&amp;nbsp;담아둘 수 있습니다. 하지만 기억하세요. 다른 사람의 글을 수집한 다음 다시 배포할 때 저작권자가 이런 행동을 허용하고 있는지 반드시 확인해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_img&quot;/&gt;
    &lt;p/&gt;&lt;img src=&quot;./modules/textyle/sample/ko/aboutTextyle1.gif&quot; id=&quot;&quot; alt=&quot;&quot;/&gt;&lt;/p&gt;
    &lt;p class=&quot;desc&quot;/&gt;글감 수집기는 &quot;글 관리 &amp;gt; 글감보관함&quot; 페이지에서 설치할 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_img&quot;/&gt;
    &lt;p/&gt;&lt;img src=&quot;./modules/textyle/sample/ko/aboutTextyle4_2.gif&quot; id=&quot;xe_img_srl_11746&quot; alt=&quot;&quot;/&gt;&lt;/p&gt;
    &lt;p class=&quot;desc&quot;/&gt;글감 수집기가 웹 브라우저의 북마크 도구모음에 설치된 화면.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_img&quot;/&gt;
    &lt;p/&gt;&lt;img src=&quot;./modules/textyle/sample/ko/aboutTextyle2_3.gif&quot; id=&quot;xe_img_srl_11750&quot; alt=&quot;&quot;/&gt;&lt;/p&gt;
    &lt;p class=&quot;desc&quot;/&gt;웹 브라우저에 설치된 &quot;글감 수집기&quot;를 이용하여 인용구를 수집하는 장면.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_hx&quot;/&gt;
    &lt;h3 id=&quot;h1247469280842&quot;/&gt;텍스타일 에디터를 사용해 보세요!&lt;/h3&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_txt&quot;/&gt;
    &lt;p/&gt;텍스타일 에디터는 텍스타일을 다른 블로깅 도구들과 차별화 하는 가장 두드러진 특징 가운데 하나 입니다. 텍스타일 에디터는 &quot;좋은 글 쓰기&quot;를 위해 개발되었고 텍스타일 에디터를 이용해서 작성된 글은 보다 논리적이고 읽기 편하며 의미있고 검색엔진과 친해질 확률이 더 높습니다. 하지만 이 도구에 익숙하지 않은 분들을 위하여 기존에 사용하시던 익숙한 에디터를 사용할 수 있도록 고려되어 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_img&quot;/&gt;
    &lt;p/&gt;&lt;img src=&quot;./modules/textyle/sample/ko/aboutTextyle3_2.gif&quot; id=&quot;&quot; alt=&quot;&quot;/&gt;&lt;/p&gt;
    &lt;p class=&quot;desc&quot;/&gt;텍스타일 에디터를 이용하여 하나의 단락을 작성하는 화면.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_hx&quot;/&gt;
    &lt;h3 id=&quot;h1247471325766&quot;/&gt;텍스타일 에디터를 조금 더 편리하게.&lt;/h3&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_list&quot;/&gt;
    &lt;ul/&gt;
        &lt;li/&gt;&lt;span/&gt;텍스타일 에디터 열기 : 1부터 9까지 사용.&lt;/span&gt;&lt;/li&gt;
        &lt;li/&gt;&lt;span/&gt;편집 모드로 전환 : &apos;Enter&apos; 또는 &apos;더블 클릭&apos; 또는 &apos;편집&apos;을 클릭.&lt;/span&gt;&lt;/li&gt;
        &lt;li/&gt;&lt;span/&gt;단락 선택 : 선택하려는 단락을 &apos;클릭&apos; 또는 &apos;방향키&apos;를 위아래로 이동하여 선택.&lt;/span&gt;&lt;/li&gt;
        &lt;li/&gt;&lt;span/&gt;선택된 단락을 이동 : &apos;Ctrl+방향키&apos; 또는 &apos;드래그&amp;amp;드롭&apos;.&lt;/span&gt;&lt;/li&gt;
    &lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_hx&quot;/&gt;
    &lt;h3 id=&quot;h1247469866936&quot;/&gt;익숙한 에디터 사용하기.&lt;/h3&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_txt&quot;/&gt;
    &lt;p/&gt;새로운것은 언제나 불편하다는 사실을 잘 알고 있습니다. 텍스타일 에디터는 기존에 사용하던 도구들과 다른 환경을 제공하고 있기 때문에 처음에는 낮설고 불편할런지도 모릅니다. 실제로 텍스타일 에디터는 좋은 글쓰기를 위해 기존의 글쓰기 환경이 제공하던 많은 것들을 포기하고 있습니다. 풍부한 표현보다 구조적인 글쓰기에 집중할 수 있도록 유도하는 과정에서 할 수 없는 일들이 생겨나게 되었습니다. 하지만 여러분이 이 불편한 도구에 익숙해지기위해 작은 노력과 주의를 기울인다면 여러분의 글은 틀림없이 예전보다 더 좋아질 것입니다. &lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_img&quot;/&gt;
    &lt;p/&gt;&lt;img src=&quot;./modules/textyle/sample/ko/aboutTextyle5_1.gif&quot; id=&quot;xe_img_srl_11752&quot; alt=&quot;&quot;/&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_txt&quot;/&gt;
    &lt;p/&gt;여전히 텍스타일 에디터가 익숙하지 않는 분들께서는 관리자 환경의 &quot;설정 &amp;gt; 쓰기환경 설정 &amp;gt; 편집방식 설정&quot; 메뉴에서 &quot;기타 편집기&quot;를 선택 하세요. &apos;XpressEditor, FCKeditor, Xquared&apos; 와 같이 기존에 여러분들이 사용하시던 익숙한 오픈소스 에디터를 그대로 사용하실 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_hx&quot;/&gt;
    &lt;h3 id=&quot;h1247460895830&quot;/&gt;스킨 편집하기.&lt;/h3&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_txt&quot;/&gt;
    &lt;p/&gt;만약 여러분이 선택한 스킨이 컬럼 구조를 유지하고 있다면 화면의 좌우 배치를 쉽게 바꿀 수 있습니다. 모든 스킨이 이렇게 컬럼 형태를 유지하고 있는것은 아니기 때문에 손쉬운 스킨 조작 화면이 존재하는 것은 아니지만 간단하게 HTML 코드를 변경하는 것으로 가능하게 됩니다&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_img&quot;/&gt;
    &lt;p/&gt;&lt;img src=&quot;./modules/textyle/sample/ko/aboutTextyle6.gif&quot; id=&quot;xe_img_srl_11743&quot; alt=&quot;&quot;/&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_txt&quot;/&gt;
    &lt;p/&gt;&quot;디자인 &amp;gt; HTML·CSS 편집 &amp;gt; HTML 편집&quot; 화면에서 두 번째 라인 &amp;lt;div id=&quot;container&quot; class=&quot;&lt;span style=&quot;font-weight: bold; text-decoration: underline;&quot;/&gt;ce&lt;/span&gt;&quot;&amp;gt; 부분을 &amp;lt;div id=&quot;container&quot; class=&quot;&lt;span style=&quot;font-weight: bold; text-decoration: underline;&quot;/&gt;ec&lt;/span&gt;&quot;&amp;gt; 으로 변경하시면 화면의 좌우 배치가 바뀝니다. 이러한 설정은 &apos;초기화&apos; 하거나 다른 스킨을 선택했을 때 사라집니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</content>
                  <category term="textyle"/>
            <category term="텍스타일"/>
            <category term="텍스타일에디터"/>
            <category term="글감수집기"/>
            
   </entry>
   <entry>
      <title>NHN DeView 2010</title>
      <id>http://www.textyle.kr/1241</id>
      <published>2010-08-16T11:55:17+09:00</published>
      <updated>2010-08-16T11:55:17+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.textyle.kr/1241"/>
      <link rel="replies" type="text/html" href="http://www.textyle.kr/1241#comment"/>
      <author>
         <name>zero</name>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p class=&quot;img&quot;&gt;&lt;img src=&quot;./files/attach/images/4/239/001/1239.gif&quot; alt=&quot;&quot;&gt;&lt;br&gt;2010 NHN deView - &lt;cite&gt;출처: &lt;a href=&quot;http://deview.naver.com/2010/main.nhn&quot;&gt;NHN DeView 2010 - &apos;무엇을 만드느냐&apos; 보다 &apos;어떻게 만드는지&apos;에 대해 공유하고 싶습니다.&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;&lt;p class=&quot;img&quot;&gt;&lt;/p&gt;&lt;p&gt;올해도 NHN DeView가 개최됩니다.&lt;br&gt;2008년부터 시작했으니 벌써 3번째가 되었네요.&lt;br&gt;저도 발표 하나 하게 되어 소개합니다. :)&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: normal; font-family: 나눔고딕, NanumGothic, 돋움, dotum, 굴림, gulim; &quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;table cellspacing=&quot;0&quot; style=&quot;margin-top: 26px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 2px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 0px; border-style: initial; border-color: initial; border-top-style: solid; border-top-color: rgb(25, 165, 206); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); table-layout: fixed; &quot;&gt;&lt;thead&gt;&lt;tr&gt;&lt;th class=&quot;blank&quot; style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 0px; border-style: initial; border-color: initial; height: 50px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(245, 245, 245); border-left-style: initial; border-left-color: initial; border-bottom-style: solid; border-bottom-color: rgb(178, 177, 174); color: rgb(109, 109, 109); text-align: center; background-position: initial initial; background-repeat: initial initial; &quot;&gt;&amp;nbsp;&lt;/th&gt;&lt;th style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 50px; background-image: url(http://deview.naver.com/2010/img/bg_th.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(178, 177, 174); color: rgb(109, 109, 109); text-align: center; background-position: initial initial; background-repeat: no-repeat no-repeat; &quot;&gt;Track A&lt;/th&gt;&lt;th style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 50px; background-image: url(http://deview.naver.com/2010/img/bg_th.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(178, 177, 174); color: rgb(109, 109, 109); text-align: center; background-position: initial initial; background-repeat: no-repeat no-repeat; &quot;&gt;Track B&lt;/th&gt;&lt;th style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 50px; background-image: url(http://deview.naver.com/2010/img/bg_th.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(178, 177, 174); color: rgb(109, 109, 109); text-align: center; background-position: initial initial; background-repeat: no-repeat no-repeat; &quot;&gt;Track C&lt;/th&gt;&lt;th style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 50px; background-image: url(http://deview.naver.com/2010/img/bg_th.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(178, 177, 174); color: rgb(109, 109, 109); text-align: center; background-position: initial initial; background-repeat: no-repeat no-repeat; &quot;&gt;Track D&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr class=&quot;white&quot;&gt;&lt;th style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 1px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 0px; border-style: initial; border-color: initial; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(250, 250, 250); border-top-style: solid; border-top-color: rgb(254, 254, 254); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-family: tahoma, verdana; font-size: 11px; color: rgb(109, 109, 109); font-weight: normal; text-align: center; background-position: initial initial; background-repeat: initial initial; &quot;&gt;10:30 ~ 11:00&lt;/th&gt;&lt;td colspan=&quot;4&quot; style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 27px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(255, 255, 255); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: initial initial; &quot;&gt;입장 및 기념품 배포&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;one&quot;&gt;&lt;th style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 1px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 0px; border-style: initial; border-color: initial; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(250, 250, 250); border-top-style: solid; border-top-color: rgb(254, 254, 254); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-family: tahoma, verdana; font-size: 11px; color: rgb(109, 109, 109); font-weight: normal; text-align: center; background-position: initial initial; background-repeat: initial initial; &quot;&gt;11:00 ~ 11:10&lt;/th&gt;&lt;td colspan=&quot;4&quot; style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 44px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;인사말&lt;br&gt;- 김평철 CTO -&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;one&quot;&gt;&lt;th style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 1px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 0px; border-style: initial; border-color: initial; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(250, 250, 250); border-top-style: solid; border-top-color: rgb(254, 254, 254); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-family: tahoma, verdana; font-size: 11px; color: rgb(109, 109, 109); font-weight: normal; text-align: center; background-position: initial initial; background-repeat: initial initial; &quot;&gt;11:10 ~ 12:00&lt;/th&gt;&lt;td colspan=&quot;4&quot; style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 44px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;키노트: 어떻게 하면 &apos;건강한&apos; 소프트웨어를 만드나? - Staged Build, 반복점진개발 방법 적용 사례&lt;br&gt;- 김정민 이사(포털개발센터장) -&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;white&quot;&gt;&lt;th style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 1px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 0px; border-style: initial; border-color: initial; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(250, 250, 250); border-top-style: solid; border-top-color: rgb(254, 254, 254); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-family: tahoma, verdana; font-size: 11px; color: rgb(109, 109, 109); font-weight: normal; text-align: center; background-position: initial initial; background-repeat: initial initial; &quot;&gt;12:00 ~ 1:20&lt;/th&gt;&lt;td colspan=&quot;4&quot; style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 27px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(255, 255, 255); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: initial initial; &quot;&gt;점심&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 1px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 0px; border-style: initial; border-color: initial; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(250, 250, 250); border-top-style: solid; border-top-color: rgb(254, 254, 254); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-family: tahoma, verdana; font-size: 11px; color: rgb(109, 109, 109); font-weight: normal; text-align: center; background-position: initial initial; background-repeat: initial initial; &quot;&gt;1:20 ~ 2:00&lt;/th&gt;&lt;td style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 64px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;네이버는 이렇게 테스트 한다 - 웹서비스 UI 테스트 자동화 (블로그 서비스 사례)&lt;br&gt;- 박선영 -&lt;/td&gt;&lt;td style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 64px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;네이버는 수천 테라바이트의 데이터를 어떻게 서비스할까?&lt;br&gt;- 김태웅 -&lt;/td&gt;&lt;td style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 64px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;한게임 사천성을 게임오븐으로 노릇노릇 구워드립니다. 덤으로 3D게임 예제까지!&lt;br&gt;- 성석현/정승범 -&lt;/td&gt;&lt;td style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 64px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;치명적인 데이터베이스 장애, 어떻게 극복할까?&lt;br&gt;- 김성규 -&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;white&quot;&gt;&lt;th style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 1px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 0px; border-style: initial; border-color: initial; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(250, 250, 250); border-top-style: solid; border-top-color: rgb(254, 254, 254); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-family: tahoma, verdana; font-size: 11px; color: rgb(109, 109, 109); font-weight: normal; text-align: center; background-position: initial initial; background-repeat: initial initial; &quot;&gt;2:00 ~ 2:10&lt;/th&gt;&lt;td colspan=&quot;4&quot; style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 27px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(255, 255, 255); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: initial initial; &quot;&gt;휴식&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 1px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 0px; border-style: initial; border-color: initial; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(250, 250, 250); border-top-style: solid; border-top-color: rgb(254, 254, 254); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-family: tahoma, verdana; font-size: 11px; color: rgb(109, 109, 109); font-weight: normal; text-align: center; background-position: initial initial; background-repeat: initial initial; &quot;&gt;2:10 ~ 2:40&lt;/th&gt;&lt;td style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 64px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;꾸준히 자라나는 소프트웨어(Software that grows!) 만들기 - 테스트 자동화, 리팩토링&lt;br&gt;- 박종빈 -&lt;/td&gt;&lt;td style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 64px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;IT에서 서버 가상화가 왜 필요한가?&lt;br&gt;- 강영상 -&lt;/td&gt;&lt;td style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 64px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;RTCS: 실시간 웹서비스, 그거 가능해?&lt;br&gt;- 김경윤 -&lt;/td&gt;&lt;td style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 64px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;&lt;b&gt;웹사이트 제작과 운영, 네이버와 함께 하세요!&lt;br&gt;- 고영수 -&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;white&quot;&gt;&lt;th style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 1px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 0px; border-style: initial; border-color: initial; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(250, 250, 250); border-top-style: solid; border-top-color: rgb(254, 254, 254); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-family: tahoma, verdana; font-size: 11px; color: rgb(109, 109, 109); font-weight: normal; text-align: center; background-position: initial initial; background-repeat: initial initial; &quot;&gt;2:40 ~ 3:00&lt;/th&gt;&lt;td colspan=&quot;4&quot; style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 27px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(255, 255, 255); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: initial initial; &quot;&gt;휴식&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 1px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 0px; border-style: initial; border-color: initial; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(250, 250, 250); border-top-style: solid; border-top-color: rgb(254, 254, 254); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-family: tahoma, verdana; font-size: 11px; color: rgb(109, 109, 109); font-weight: normal; text-align: center; background-position: initial initial; background-repeat: initial initial; &quot;&gt;3:00 ~ 3:40&lt;/th&gt;&lt;td style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 64px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;개발자가 좋아하는 기획서 만들기&lt;br&gt;- 이기현 -&lt;/td&gt;&lt;td style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 64px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;Arcus: 당신의 서비스가 점점 느려진다구요?&lt;br&gt;- 안성화 -&lt;/td&gt;&lt;td style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 64px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;WolfBoy를 통한 한게임의 애플 앱스토어 첫 도전기&lt;br&gt;- 김은경 -&lt;/td&gt;&lt;td style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 64px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;네이버 안의 또다른 세상, 함께 만드는 네이버 소셜 앱&lt;br&gt;- 오창훈 -&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;white&quot;&gt;&lt;th style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 1px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 0px; border-style: initial; border-color: initial; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(250, 250, 250); border-top-style: solid; border-top-color: rgb(254, 254, 254); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-family: tahoma, verdana; font-size: 11px; color: rgb(109, 109, 109); font-weight: normal; text-align: center; background-position: initial initial; background-repeat: initial initial; &quot;&gt;3:40 ~ 3:50&lt;/th&gt;&lt;td colspan=&quot;4&quot; style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 27px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(255, 255, 255); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: initial initial; &quot;&gt;휴식&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 1px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 0px; border-style: initial; border-color: initial; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(250, 250, 250); border-top-style: solid; border-top-color: rgb(254, 254, 254); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-family: tahoma, verdana; font-size: 11px; color: rgb(109, 109, 109); font-weight: normal; text-align: center; background-position: initial initial; background-repeat: initial initial; &quot;&gt;3:50 ~ 4:20&lt;/th&gt;&lt;td style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 64px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;Goodbye 점검 공지 - 서비스 중단없는 점검 수행&lt;br&gt;- 김주관 -&lt;/td&gt;&lt;td style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 64px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;단 하루도 안심할 수 없게 만드는 웹 보안 위협들 - 어떻게 맞설까?&lt;br&gt;- 조상현 -&lt;/td&gt;&lt;td style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 64px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;게임 테스트 자동화, 하면 된다 - 웹보드게임, RPG게임 테스트 자동화 사례&lt;br&gt;- 김신애 -&lt;/td&gt;&lt;td style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 64px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;네이버 오픈API 제공 방안&lt;br&gt;- 김기영 -&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;white&quot;&gt;&lt;th style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 1px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 0px; border-style: initial; border-color: initial; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(250, 250, 250); border-top-style: solid; border-top-color: rgb(254, 254, 254); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-family: tahoma, verdana; font-size: 11px; color: rgb(109, 109, 109); font-weight: normal; text-align: center; background-position: initial initial; background-repeat: initial initial; &quot;&gt;4:20 ~ 4:30&lt;/th&gt;&lt;td colspan=&quot;4&quot; style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 27px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(255, 255, 255); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: initial initial; &quot;&gt;휴식&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 1px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 0px; border-style: initial; border-color: initial; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(250, 250, 250); border-top-style: solid; border-top-color: rgb(254, 254, 254); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-family: tahoma, verdana; font-size: 11px; color: rgb(109, 109, 109); font-weight: normal; text-align: center; background-position: initial initial; background-repeat: initial initial; &quot;&gt;4:30 ~ 5:00&lt;/th&gt;&lt;td style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 64px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;모바일앱 모바일과 서비스를 함께 담는 그릇만들기 체험기&lt;br&gt;- 신재경 -&lt;/td&gt;&lt;td style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 64px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;통계로 알아보는 DDoS&lt;br&gt;- 홍상현 -&lt;/td&gt;&lt;td style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 64px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;한게임의 첫 Facebook SNG 도전. 높은 진입장벽 앞의 실패, 그리고 가능성&lt;br&gt;- 김기용 -&lt;/td&gt;&lt;td style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 64px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;NHN 웹플랫폼, 세상 밖으로&lt;br&gt;- 김성관 -&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 1px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 0px; border-style: initial; border-color: initial; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(250, 250, 250); border-top-style: solid; border-top-color: rgb(254, 254, 254); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-family: tahoma, verdana; font-size: 11px; color: rgb(109, 109, 109); font-weight: normal; text-align: center; background-position: initial initial; background-repeat: initial initial; &quot;&gt;5:00 ~ 5:30&lt;/th&gt;&lt;td colspan=&quot;4&quot; style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; height: 64px; background-image: url(http://deview.naver.com/2010/img/bg_td.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 252, 253); border-left-style: solid; border-left-color: rgb(235, 235, 235); border-bottom-style: solid; border-bottom-color: rgb(235, 235, 235); font-size: 11px; color: rgb(109, 109, 109); letter-spacing: -1px; line-height: 14px; text-align: center; background-position: initial initial; background-repeat: no-repeat repeat; &quot;&gt;폐회 &amp;amp; 경품추첨&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;2시 10분 D 트랙에서 &quot;웹사이트 제작과 운영, 네이버와 함께 하세요&quot; 라는 제목으로 발표합니다.&lt;br&gt;이번에는 XpressEngine 뿐 아니라 웹사이트 운영시 필수적이라고도 할 수 있는 여러 API 들에 대한 소개도 같이 합니다.&lt;br&gt;제작은 XE로 운영은 NHN이 제공하는 다양한 OpenAPI로 할 수 있다는 내용으로 발표할 예정입니다.&lt;br&gt;많은 관심 부탁드릴께요. 꾸벅.&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>Guidelines for Online Success - Taschen</title>
      <id>http://www.textyle.kr/1143</id>
      <published>2010-08-14T16:17:43+09:00</published>
      <updated>2010-08-19T13:43:58+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.textyle.kr/1143"/>
      <link rel="replies" type="text/html" href="http://www.textyle.kr/1143#comment"/>
      <author>
         <name>Aslan</name>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;h4 id=&quot;h1281770614247&quot;&gt;성공적인 웹사이트 디자인 가이드라인 - 1&lt;/h4&gt;&lt;p&gt;오늘 부터 웹사이트 기획 및 설계에 대한 사례를 중심으로 반드시 해야할 것과 하지 말아야 할것에 대해 기술한 책 한권을 가지고 한 주제씩 번역을 해볼까한다. 선택한 책은 Taschen에서 발행한 &quot;&lt;a href=&quot;http://www.taschen.com/lookinside/05204/index.htm&quot; target=&quot;_blank&quot;&gt;Guidelines for Online Success&lt;/a&gt;&quot;라는 책인데 전체적인 내용은 그림책 처럼 보기 쉽게 되어 있으면서도 기억에 오래 남을 수 있는 말들로 구성되어져 있다.&amp;nbsp;&lt;br&gt;&lt;br&gt;&amp;nbsp;Contents&lt;br&gt;&lt;br&gt;1. Interface &amp;amp; Design&lt;br&gt;2. Marketing &amp;amp; Communication&lt;br&gt;3. Technology &amp;amp; Programming&lt;br&gt;4. Technical Advice&lt;br&gt;5. Contents/Contents Management&lt;br&gt;6. E-Commerce&lt;br&gt;&lt;br&gt;&amp;nbsp;총 6장의 챕터로 구성되어져 있고 각각의 챕터는 실제 인터넷에 구축 되어져 있는 사이트들을 예시로 들어 놓았다.&lt;br&gt;&amp;nbsp;대부분의 내용은 책에 있는 내용들을 그대로 인용할 예정이고 추가로 더 좋은 사례가 있다면 그것들까지 포함해서 설명할 예정이다. &lt;br&gt;&amp;nbsp;이 책의 서문에 이런 문구가 있다. &quot;Do Read this book, Don&apos;t Let it collect dust&quot; 해석하자면 &apos;이 책에 먼지가 쌓이지 않도록 자주 책을 읽어라&apos;이다. 그만큼 잘 활용하라 라는 얘기.. 자, 그럼 시작~~~&lt;/p&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;h4 id=&quot;h1281765719742&quot;&gt;1. Interface &amp;amp; Design&lt;/h4&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14px; &quot;&gt;&lt;b&gt;Color&lt;/b&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;색은 커뮤니케이션의 한 형태이다. 관심과 사랑을 가지고 색을 잘 사용한다면 커뮤니케이션에 있어서 매우 강력한 무기가 될 수 있다. 색은 사용자들에게 행복감을 주고 슬프게도 하며 가장 큰 능력을 사랑이라는 감정을 느끼게 하는것. 이 모든 것들은 색을 사용함에 있어서 얼마나 신중하느냐에 달려있다.색을 음악이라고 가정(&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(45, 45, 45); font-family: 네이버사전, naverdic, 새굴림, 굴림, gulim, sans-serif; &quot;&gt;&lt;a href=&quot;http://krdic.naver.com/small_detail.nhn?docid=391400&quot; class=&quot;b_text&quot; style=&quot;color: rgb(0, 71, 182); text-decoration: none; &quot;&gt;假定&lt;/a&gt;)&lt;/span&gt;해보면 슬픔을 느끼게 해주는 음악이 될 수 있고 또 어떤 음악은 형용할 수 없는 경이로움도 줄 수 있는 것이다. 웹사이트의 색은 영화음악과 같다고 할 수 있다.&lt;br&gt;&amp;nbsp;색을 볼 수 있는 눈을 가졌다면, 즉, 잘 활용할 수 있는 능력이 있다면 기억에 오래남을 순간을 만들 수 있들 것이라고 생각한다. 색을 사용함에 있어서 어떤 규칙도 없다. 다만, 적게사용 또는 많게사용 라는 옵션만이 있을 뿐... &amp;nbsp;&lt;/p&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;p class=&quot;img&quot; style=&quot;text-align: left; &quot;&gt;&lt;img src=&quot;./files/attach/images/848/143/001/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202010-08-14%20%EC%98%A4%ED%9B%84%203.47.40.png&quot; width=&quot;411&quot; height=&quot;509&quot; class=&quot;xe_filesrl_1150&quot;&gt;&lt;/p&gt;&lt;p&gt;위의 내용이 색을 사용함에 있어서 해야할 것과 하지 말아야할 것에 대해 3가지씩 정리해 놓은 것이다. 그중에 눈의 띄는 내용은 해야할 것 중 두번째, 전달하고 싶은 것이 무엇인지를 정확하게 알고 그것을 정확하게 표현해줄 색을 찾는 것이 중요하다라는 것, 그리고 하지말아야 할 것 중에서 첫번째, 너무 많은 색을 사용하지 말 것. 두번째 가능한 사용자들이 주목할 수 있는 밝은 색을 사용하고 가능한 균형과 조화를 이루어서 사용하라. 세번째, 다른 사람의 색을 흉내내지 마라 &amp;nbsp;등이다.&lt;br&gt;&lt;br&gt;&amp;nbsp;색이란 어떻게 쓰였느냐에 따라서 사용자들이 편안하고 기분 좋게 느낄수도, 또는 산만하거나 어렵게 느낄 수도 있는 매우 사용하기 어려운 요소이다. 하지만 웹에서 뭔가를 표현하기 위해서는 반드시 사용되는 요소이며, 단순 표현이 아닌 생각의 효과적인 전달을 위해서는 상황에 맞는, 적절한 균형을 유지한 상태로 색을 사용해야 한다. &amp;nbsp;&lt;br&gt;&lt;br&gt;&amp;nbsp;색은 표현을 더욱 섬세하게 만들어주고 느끼을 배가 시켜주기 때문이다.&amp;nbsp;&lt;/p&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;/div&gt;</content>
                  <category term="book"/>
            <category term="taschen"/>
            <category term="design"/>
            
   </entry>
   <entry>
      <title>Youtube 동영상에서 MP3음원 추출하기</title>
      <id>http://www.textyle.kr/998</id>
      <published>2010-08-11T23:09:28+09:00</published>
      <updated>2010-08-19T11:43:45+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.textyle.kr/998"/>
      <link rel="replies" type="text/html" href="http://www.textyle.kr/998#comment"/>
      <author>
         <name>Aslan</name>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;&lt;font class=&quot;Apple-style-span&quot; face=&quot;Dotum&quot;&gt;&amp;nbsp;가끔 TV CF에 삽입된 곡들 중에서 귀에 쏙 들어오는 음악을 듣게 되면 그 곡이&amp;nbsp;뭔지 인터넷을 다 뒤져서 찾아내서 유료로 다운로드 받곤 한다.&amp;nbsp;물론 이 경우 국내에서 발매 된 앨범에 한하고 개별곡으로 판매가 안되는&amp;nbsp;곡일 경우는 그 곡이 포함된 앨범을 구입해야만 원하는 음악을 들을 수 있다.&lt;br&gt;&lt;br&gt;&amp;nbsp;그런데, 원하는 곡이 어떤 음악인지만 알면 &lt;a href=&quot;http://www.youtube.com&quot; target=&quot;_blank&quot;&gt;Youtube&lt;/a&gt;를 활용해서 MP3음원을&amp;nbsp;추출할 수 있다. 물론 무료로 할 수 있고, 대부분 Pop이나 Jazz 가요도 할 수 있다.^^&lt;br&gt; &lt;br&gt;&amp;nbsp;그 방법은 아래와 같다.&lt;br&gt; &lt;br&gt;&amp;nbsp;1. 원하는 음악의 제목과, 가수명, 앨범명을 인터넷을 통해 찾는다.&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; (iPhone 소지자의 경우 &lt;a href=&quot;http://itunes.apple.com/us/app/soundhound/id355554941?mt=8&amp;amp;ign-mpt=uo%3D2&quot; target=&quot;_blank&quot;&gt;Soundhound&lt;/a&gt; 어플을 활용하면 쉽게 찾을 수 있다.)&amp;nbsp;&lt;br&gt;&lt;br&gt;&amp;nbsp;2. 찾은 음악의 가수명과 제목으로 Youtube에서 검색한다. 이 경우&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; 같은 음악이긴 하나 여러가지의 형태의 동영상이 검색되어 지는데&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; 가급적, Official 이라는 표현이 있는 동영상을 선택하도록 한다.&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; 아래 검색 결과를 보면 위에서 세번째 결과에 Official이라고 표현 되어 있는 것을 볼 수 있다.&lt;/font&gt;&lt;/p&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;p class=&quot;img&quot; style=&quot;text-align: left; &quot;&gt;&lt;img src=&quot;./files/attach/images/848/998/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202010-08-11%20%EC%98%A4%ED%9B%84%2010.44.41.png&quot; width=&quot;591&quot; height=&quot;594&quot; class=&quot;xe_filesrl_1005&quot;&gt;&lt;br&gt;Youtube 검색결과&lt;/p&gt;&lt;p&gt;&amp;nbsp;3. &lt;a href=&quot;http://www.dirpy.com&quot; target=&quot;_blank&quot;&gt;Dirpy.com&lt;/a&gt;에 접속한 후 Youtube에서 찾은 검색결과 URL을 복사하여&amp;nbsp;dirpy! 입력창에 붙여넣는다.&lt;/p&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;p class=&quot;img&quot; style=&quot;text-align: left; &quot;&gt;&lt;img src=&quot;./files/attach/images/848/998/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202010-08-11%20%EC%98%A4%ED%9B%84%2010.55.22.png&quot; width=&quot;591&quot; height=&quot;535&quot; class=&quot;xe_filesrl_1006&quot;&gt;&lt;/p&gt;&lt;p&gt;4. dirpy.com에 입력한 동영상이 맞는지 확인한 후 ID3 Tag를 원하는&amp;nbsp;형태로 수정한 후에 다운 받을 MP3의 Bitrate를 정한 후&amp;nbsp;Download 버튼을 누르면 선택한 동영상에 추출한 MP3음원이&amp;nbsp;다운로드 된다.&amp;nbsp;그리고 동영상 포맷으로도 다운로드 할 수 있는데, 선택한 동영상의&amp;nbsp;퀄리티에 따라서 다운로드 받을 수 있는 포맷이 달라진다.&amp;nbsp;예를들어 동영상이 HD버전으로 480p 정도로 만들어졌다면&amp;nbsp;다운로드 가능한 동영상 포맷은,&amp;nbsp;240p.flv, 360p.flv, 360p.mp4, 480.flv 이렇게 4가지 버전이다.&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;p class=&quot;img&quot; style=&quot;text-align: left; &quot;&gt;&lt;img src=&quot;./files/attach/images/848/998/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202010-08-11%20%EC%98%A4%ED%9B%84%2010.50.55.png&quot; width=&quot;591&quot; height=&quot;537&quot; class=&quot;xe_filesrl_1028&quot;&gt;&lt;br&gt;dirpy 검색결과&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;이렇게 원하는 음악의 동영상이 Youtube에 존재한다면 얼마든지&amp;nbsp;MP3로 추출하여 음악을 들을 수 있다.&amp;nbsp;현재 dirpy.com은 베타서비스이긴 하지만 앞으로&amp;nbsp;저작권 문제만&amp;nbsp;저촉되지 않는다면 좋은 음악을&amp;nbsp;얼마든지 무료로 얻을 수 있다는 점에서 매우 유용한 서비스라는&amp;nbsp;생각이 든다.&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;자, 이제 음악파일 얻으려고 여기저기 기웃거리지 말고 Youtube와 dirpy.com을&amp;nbsp;통해서 원하는 음악을 무제한 다운로드 받아보자.&lt;/p&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;/div&gt;</content>
                  <category term="dirpy"/>
            <category term="Youtube"/>
            <category term="mp3"/>
            <category term="다운로드"/>
            <category term="무료"/>
            
   </entry>
   <entry>
      <title>팀원이 건네준 책한권</title>
      <id>http://www.textyle.kr/960</id>
      <published>2010-08-10T16:15:52+09:00</published>
      <updated>2010-08-19T11:44:32+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.textyle.kr/960"/>
      <link rel="replies" type="text/html" href="http://www.textyle.kr/960#comment"/>
      <author>
         <name>Aslan</name>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum;&quot;&gt;﻿오늘 아침에 우리 팀원 중 한 명이 팀 전체(7명)에게 책 한권씩을 선물했다.&lt;br&gt;&lt;br&gt;&amp;nbsp;&quot;미스터 코칭&quot; - 마음의 문을 여는 열쇠 저자 : 김두형&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot; class=&quot;img&quot;&gt;&lt;img class=&quot;xe_filesrl_961&quot; rawsrc=&quot;./files/attach/images/848/960/%EC%82%AC%EC%A7%84.JPG&quot; src=&quot;./files/attach/images/848/960/%EC%82%AC%EC%A7%84.JPG.resized.JPG&quot; height=&quot;599&quot; width=&quot;449&quot;&gt;&lt;br&gt;&quot;미스터 코칭&quot; - 마음의 문을 여는 열쇠 저자 : 김두형&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum;&quot;&gt;커뮤니케이션, 리더십에 대한 좋은 사례들이 나와있는 길잡이 도서를&lt;br&gt;
전원에게 선물한 것이다.&amp;nbsp;모두가 한번씩 읽어보면 좋을것 같다라며..ㅋㅋ&lt;br&gt;&lt;br&gt;&amp;nbsp;IT쪽에서 근무하는 사람들의 일상적인 생활은 근무시간에 자신의 모니터나&lt;br&gt;
노트북만을 들여다보고 하루를 보내게 되는 경우가 대다수일 것이다.&lt;br&gt;게다가 협업이 없는 업무로 가득한 우리 팀 같은 경우는 특별한 경우를 빼면&lt;br&gt;하루중 팀원들끼리 자주 대화를 하는 것이 쉽지 않은게 현실이다.&lt;br&gt;&amp;nbsp;자연스레 가까워지는 것이 아니라 자연스레 멀어지거나 가까워지지도 멀어지지도 않는&lt;br&gt;평행선 같은 관계를 유지하게 되는 상황인것이다.&lt;br&gt;&lt;br&gt;&amp;nbsp;하루중 보내는 시간을 따져보면 가족 보다도 더 많은 시간을 함께 같은 공간안에 있게&lt;br&gt;되는 셈이지만 서로 특별한 관심을 가지지 않고 생활을 하다보면 그냥 저 사람은 &lt;br&gt;우리 팀이었어 정도의 유대감 정도밖에 가지지 못하게 된다.&lt;br&gt;&lt;br&gt;&amp;nbsp;그래서 커뮤니케이션이나 팀웍에 대한 얘기를 자주 하곤 하는데 이 책을 선물해준&lt;br&gt;팀원이 내 기대에 부응이라도 하는 것 처럼 이런 좋은 선물을 전달해줬다.&lt;br&gt;그것도 책을 받을 사람에게 전달할 내용을 직접 일일히 앞장에 적어서...&lt;br&gt;&lt;br&gt;&amp;nbsp;이런 이벤트가 직장 생활하면서 소소한 즐거움을 주는 것이 아닐지..&lt;br&gt;또, 이런 계기가 서로의 친밀감을 더 공고히 하는 촉매제가 아닐지..&lt;br&gt;&lt;br&gt;&amp;nbsp;암튼 이 책 선물을 준 팀원이 정말 고맙다.. &amp;nbsp; &lt;/span&gt;&lt;br&gt;&lt;/p&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;/div&gt;</content>
                  <category term="리더쉽"/>
            <category term="커뮤니케이션"/>
            
   </entry>
   <entry>
      <title>사용자 친화적 메세지-Dropbox</title>
      <id>http://www.textyle.kr/935</id>
      <published>2010-08-10T11:43:03+09:00</published>
      <updated>2010-08-10T11:47:52+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.textyle.kr/935"/>
      <link rel="replies" type="text/html" href="http://www.textyle.kr/935#comment"/>
      <author>
         <name>Aslan</name>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum;&quot;&gt;아침에 메일을 확인해보니 재미있는 제목의 메일이 메일이 보인다.&lt;br&gt;&lt;br&gt;&quot;Come back to Dropbox!&quot;&lt;br&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;클라우드 서비스인 &lt;a target=&quot;_blank&quot; href=&quot;http://www.dropbox.com&quot;&gt;Dropbox&lt;/a&gt;에서 온 메일인데 그 내용이 매우 귀엽다(?)..&lt;br&gt;&lt;br&gt;&amp;nbsp;내용을 해석해보면, (직역이 더 느낌이 빡...ㅋ)&lt;br&gt;&lt;br&gt;&apos;그동안 Dropbox에 방문하지 않으셨군요.. 요즘 Dropbox가 외롭습니다.&lt;br&gt;&amp;nbsp; 저희 Dropbox는 &lt;br&gt;&amp;nbsp; - 당신의 컴퓨터에 있는 파일들을 웹과 동기화 할 수 있고&lt;br&gt;&amp;nbsp; - 어디서든 접근할 수 있고 백업도 가능하며&lt;br&gt;&amp;nbsp; - 대용량 파일과 사진등을 쉽게 공유 할 수 있습니다.&lt;br&gt;&lt;br&gt;  우리는 당신이 다시 Dropbox로 돌아오기를 희망합니다.&apos;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -Dropbox team&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot; class=&quot;img&quot;&gt;&lt;img class=&quot;xe_filesrl_936&quot; rawsrc=&quot;./files/attach/images/848/935/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202010-08-10%20%EC%98%A4%EC%A0%84%2010.51.38.png&quot; src=&quot;./files/attach/images/848/935/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202010-08-10%20%EC%98%A4%EC%A0%84%2010.51.38.png.resized.png&quot; height=&quot;599&quot; width=&quot;540&quot;&gt;&lt;br&gt;Dropbox e-mail&lt;/p&gt;&lt;p&gt;요즘은 사용자에게 재방문과 적극적인 사용을 권하는 메일을 하루에도&lt;br&gt;수도 없이 받는다.&lt;br&gt;&amp;nbsp;대부분 컨텐츠의 일부를 보여주는 일종의 홍보전단지 같은 뉴스레터 형식이&lt;br&gt;거의 대부분인데 그런 와중에 이렇게 편지형태로 사용해달라는 애교를&lt;br&gt;부리는 서비스는 드물지 않나라는 생각이 든다.&lt;br&gt;&lt;br&gt;&amp;nbsp;사용자에게 친근하게 다가가는 방법은 여러가지가 있고 끊임없이&lt;br&gt;새로운 기법의 홍보 수단을 통해 서비스 사업자들은 사용자들에게 어필하지만&lt;br&gt;이렇게 그냥 편하게 친구가 보낸 메일처럼 사용해 줘~ 라는 식의 표현으로&lt;br&gt;다가가는 방법도 매우 좋은 방법인것 같다.&lt;br&gt;&lt;br&gt;&amp;nbsp;물론 이 메일 또한 정형화된 메일 폼으로 발송되어졌을 것이다. 하지만 &lt;br&gt;이 메일 한통을 보면서 살짝 미소짓게 되는 나 같은 Dropbox 사용자들은&lt;br&gt;다른 서비스 보다 Dropbox에 대해서 더 loyalty를 가지게 되지 않을까라는 생각이든다.&lt;br&gt;&lt;br&gt;&amp;nbsp;국내에도 클라우드 서비스들이 하나둘씩 생겨나고 있다.&lt;br&gt;&lt;br&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://ndrive.naver.com/&quot;&gt;네이버 N드라이브&lt;/a&gt;는 10GB를 , &lt;a target=&quot;_blank&quot; href=&quot;http://www.ucloud.com&quot;&gt;KT ucloud&lt;/a&gt;는 20GB(KT 서비스가입자들에 한해서)를 무료로 제공한다.&lt;br&gt;&lt;br&gt;&amp;nbsp;국내 서비스들도 Dropbox처럼 고객친화적인 사용자 경험을 제공하는데 &lt;br&gt;게을리 하지 않았으면 하는 바램을 가져본다.&lt;br&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  <category term="dropbox"/>
            <category term="ux"/>
            
   </entry>
   <entry>
      <title>구글이 제공하는 컨텐츠 수집기 Google Alert.</title>
      <id>http://www.textyle.kr/878</id>
      <published>2010-08-09T17:49:06+09:00</published>
      <updated>2010-08-09T22:34:17+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.textyle.kr/878"/>
      <link rel="replies" type="text/html" href="http://www.textyle.kr/878#comment"/>
      <author>
         <name>Aslan</name>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;p&gt;웹에는 엄청난 양의 정보가 존재한다. &lt;br&gt;이글을 쓰고 있는 이 순간에도 무수히 많은 정보가 웹에 올라오고 없어지는 것을 반복할 것이다.&lt;br&gt;그래서 웹을 통해 전문적인 정보나 딱 내가 원하는 정보를 찾을 때는 검색엔진에서 어느정도의&lt;br&gt;시간을 소비해야 하는 노력을 감수해야만 한다.&lt;br&gt; &lt;br&gt;&amp;nbsp;이런 경우를 위해 Google에서 &lt;a href=&quot;http://www.google.com/alerts&quot; target=&quot;_blank&quot;&gt;Google Alert&lt;/a&gt;라는 서비스를 내놓았다.[그림 1] &amp;nbsp;&lt;/p&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;p class=&quot;img&quot; style=&quot;text-align: left; &quot;&gt;&lt;img src=&quot;./files/attach/images/848/878/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202010-08-09%20%EC%98%A4%ED%9B%84%209.35.02.png.resized.png&quot; width=&quot;600&quot; height=&quot;501&quot; rawsrc=&quot;./files/attach/images/848/878/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202010-08-09%20%EC%98%A4%ED%9B%84%209.35.02.png&quot; class=&quot;xe_filesrl_908&quot;&gt;&lt;br&gt;[그림 1] Google Alert 초기화면&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Dotum; &quot;&gt;이 서비스는 사용자가 원하는 키워드에 의해서 새롭게 웹에 공개되는 정보를 모니터링 할 수 있는&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;font-family: Dotum; &quot;&gt;서비스이다.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style=&quot;font-family: Dotum; &quot;&gt;&amp;nbsp;예를들어 &apos;박지성&apos;에 대한 뉴스가 올라올때 마다 그 내용을 메일로 받고 싶다고 했을때,&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;font-family: Dotum; &quot;&gt;아래와 같이 설정하면 검색을 하지 않아도 Google에 등록되는 정보들은 자동으로&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;font-family: Dotum; &quot;&gt;메일을 통해 전달이 된다는 것이다. 수신방법을 feed로 하면 Google Reader로도 수신할 수 있다.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style=&quot;font-family: Dotum; &quot;&gt;&lt;b&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal;&quot;&gt;	  &lt;/span&gt;&lt;/span&gt;검색어 : 박지성, 맨유&lt;/b&gt;&lt;/span&gt;&lt;b&gt;&lt;br&gt;&lt;/b&gt;&lt;span style=&quot;font-family: Dotum; &quot;&gt;&lt;b&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt;	&lt;/span&gt;종류 &amp;nbsp; &amp;nbsp;: 전체(블로그,뉴스,토론 중 택일 가능)&lt;/b&gt;&lt;/span&gt;&lt;b&gt;&lt;br&gt;&lt;/b&gt;&lt;span style=&quot;font-family: Dotum; &quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre; font-family: Dotum; &quot;&gt;&lt;b&gt;	&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Dotum; &quot;&gt;&lt;b&gt;빈도 &amp;nbsp; &amp;nbsp;: 하루에 한번 (또는 일주일에 한번)&lt;/b&gt;&lt;/span&gt;&lt;b&gt;&lt;br&gt;&lt;/b&gt;&lt;span style=&quot;font-family: Dotum; &quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre; font-family: Dotum; &quot;&gt;&lt;b&gt;	&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Dotum; &quot;&gt;&lt;b&gt;이메일 길이 : 최대 20개 (또는 50개)&lt;/b&gt;&lt;/span&gt;&lt;b&gt;&lt;br&gt;&lt;/b&gt;&lt;span style=&quot;font-family: Dotum; &quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre; font-family: Dotum; &quot;&gt;&lt;b&gt;	&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Dotum; &quot;&gt;&lt;b&gt;이메일주소 : 정보를 받을 이메일 주소(RSS Feed로도 설정 가능)&lt;/b&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style=&quot;font-family: Dotum; &quot;&gt;[그림2]에서 보는 것처럼 전달되는 정보를 미리보기 할 수도 있다.&lt;/span&gt;&lt;br&gt;&lt;font class=&quot;Apple-style-span&quot; face=&quot;Dotum&quot;&gt;&lt;br&gt;&lt;/font&gt;&lt;/p&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&gt;&amp;lt;/iframe&gt;&lt;/div&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;p class=&quot;img&quot; style=&quot;text-align: left; &quot;&gt;&lt;img src=&quot;./files/attach/images/848/878/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202010-08-09%20%EC%98%A4%ED%9B%84%2010.03.16.png.resized.png&quot; width=&quot;600&quot; height=&quot;500&quot; rawsrc=&quot;./files/attach/images/848/878/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202010-08-09%20%EC%98%A4%ED%9B%84%2010.03.16.png&quot; class=&quot;xe_filesrl_909&quot;&gt;&lt;br&gt;[그림 2]&lt;/p&gt;&lt;p&gt;로그인을 하면 Google Alert를 편집할 수 있는 관리자 모드가 제공된다. 관리자 모드에서는&lt;br&gt;개별 Alert의 수신방법, 빈도수 등을 조절할 수 있다.&lt;br&gt;&lt;br&gt;&amp;nbsp;정보를 많이 접하는 사람들 대부분이 자동으로 원하는 정보를 제공받기 위헤 RSS feed를 사용하는데, &lt;br&gt;구독하는 feed가 많아지면 그 안에서도 원하는 정보를 찾는것이 쉽지 않다.&lt;br&gt;&lt;br&gt;&amp;nbsp;그럴 경우에 Google Alert를 사용하면 좀 더 원하는 정보로의 접근이 쉬워질 것이라 생각된다.&lt;br&gt;&lt;br&gt;다른 한편으로 생각해보면 사용자들에게 Google로의 접근성을 더 확보하고자 하는 전략이&lt;br&gt;숨어 있기는 하지만 사용자 입장에서는 분명 편리한 서비스라는 생각이 든다.&lt;/p&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;div id=&quot;__KO_DIC_LAYER__&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; position: fixed; z-index: 1e+09; overflow-x: hidden; overflow-y: hidden; border-top-width: 2px; border-right-width: 2px; border-bottom-width: 2px; border-left-width: 2px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(51, 51, 119); border-right-color: rgb(51, 51, 119); border-bottom-color: rgb(51, 51, 119); border-left-color: rgb(51, 51, 119); display: none; &quot;&gt;&amp;lt;iframe frameborder=&quot;0&quot; scrolling=&quot;yes&quot; style=&quot;width: 100%; height: 100%; background-color: rgb(255, 255, 255); &quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/div&gt;&lt;/div&gt;</content>
                  <category term="google"/>
            <category term="alert"/>
            <category term="contents"/>
            
   </entry>
   <entry>
      <title>텍스타일의 세계로 오신것을 환영합니다!</title>
      <id>http://www.textyle.kr/774</id>
      <published>2010-08-06T16:36:24+09:00</published>
      <updated>2010-08-06T16:36:24+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.textyle.kr/774"/>
      <link rel="replies" type="text/html" href="http://www.textyle.kr/774#comment"/>
      <author>
         <name>똥똥</name>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;div class=&quot;eArea xe_content xe_dr_txt&quot;&gt;
    &lt;p&gt;더 좋은 글쓰기를 위해 어떤 도움이 필요할까요? 더 쉬운 글쓰기를 위해서는요? 텍스타일은 &quot;더 좋은 글을 더 쉽게 쓰고싶다&quot;는 욕구로 부터 시작되었습니다. 만약 지금 여러분&amp;nbsp;곁에 좋은 글쓰기 선생님을 둘 수 없다면 텍스타일을 선택한 것은 무척 고무적인 일입니다. 텍스타일의 글쓰기 도구는 조금 특별 하거든요. ^^ 함께 만나 보시죠!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_hx&quot;&gt;
    &lt;h3 id=&quot;h1247467217012&quot;&gt;글감 수집기를 설치해 보세요!&lt;/h3&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_txt&quot;&gt;
    &lt;p&gt;좋은 글에는 항상 참조와 인용이 따릅니다. 글감 수집기는 좋은 글이&amp;nbsp;보다 많은 사람들의 글과 객관적인 사실을 참조하고 있다는 사실에 주목하였고 글을 쓰는 과정에서 이러한 작업을 보다 편리하게 할 수 있도록 도울 것입니다. &quot;글감 수집기&quot;를 여러분의 브라우징 도구에 북마크 하시면 웹 서핑 도중 참조하거나 인용하고 싶은 글을 여러분의 텍스타일에&amp;nbsp;담아둘 수 있습니다. 하지만 기억하세요. 다른 사람의 글을 수집한 다음 다시 배포할 때 저작권자가 이런 행동을 허용하고 있는지 반드시 확인해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_img&quot;&gt;
    &lt;p&gt;&lt;img src=&quot;./modules/textyle/sample/ko/aboutTextyle1.gif&quot; id=&quot;&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
    &lt;p class=&quot;desc&quot;&gt;글감 수집기는 &quot;글 관리 &amp;gt; 글감보관함&quot; 페이지에서 설치할 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_img&quot;&gt;
    &lt;p&gt;&lt;img src=&quot;./modules/textyle/sample/ko/aboutTextyle4_2.gif&quot; id=&quot;xe_img_srl_11746&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
    &lt;p class=&quot;desc&quot;&gt;글감 수집기가 웹 브라우저의 북마크 도구모음에 설치된 화면.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_img&quot;&gt;
    &lt;p&gt;&lt;img src=&quot;./modules/textyle/sample/ko/aboutTextyle2_3.gif&quot; id=&quot;xe_img_srl_11750&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
    &lt;p class=&quot;desc&quot;&gt;웹 브라우저에 설치된 &quot;글감 수집기&quot;를 이용하여 인용구를 수집하는 장면.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_hx&quot;&gt;
    &lt;h3 id=&quot;h1247469280842&quot;&gt;텍스타일 에디터를 사용해 보세요!&lt;/h3&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_txt&quot;&gt;
    &lt;p&gt;텍스타일 에디터는 텍스타일을 다른 블로깅 도구들과 차별화 하는 가장 두드러진 특징 가운데 하나 입니다. 텍스타일 에디터는 &quot;좋은 글 쓰기&quot;를 위해 개발되었고 텍스타일 에디터를 이용해서 작성된 글은 보다 논리적이고 읽기 편하며 의미있고 검색엔진과 친해질 확률이 더 높습니다. 하지만 이 도구에 익숙하지 않은 분들을 위하여 기존에 사용하시던 익숙한 에디터를 사용할 수 있도록 고려되어 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_img&quot;&gt;
    &lt;p&gt;&lt;img src=&quot;./modules/textyle/sample/ko/aboutTextyle3_2.gif&quot; id=&quot;&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
    &lt;p class=&quot;desc&quot;&gt;텍스타일 에디터를 이용하여 하나의 단락을 작성하는 화면.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_hx&quot;&gt;
    &lt;h3 id=&quot;h1247471325766&quot;&gt;텍스타일 에디터를 조금 더 편리하게.&lt;/h3&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_list&quot;&gt;
    &lt;ul&gt;
        &lt;li&gt;&lt;span&gt;텍스타일 에디터 열기 : 1부터 9까지 사용.&lt;/span&gt;&lt;/li&gt;
        &lt;li&gt;&lt;span&gt;편집 모드로 전환 : &apos;Enter&apos; 또는 &apos;더블 클릭&apos; 또는 &apos;편집&apos;을 클릭.&lt;/span&gt;&lt;/li&gt;
        &lt;li&gt;&lt;span&gt;단락 선택 : 선택하려는 단락을 &apos;클릭&apos; 또는 &apos;방향키&apos;를 위아래로 이동하여 선택.&lt;/span&gt;&lt;/li&gt;
        &lt;li&gt;&lt;span&gt;선택된 단락을 이동 : &apos;Ctrl+방향키&apos; 또는 &apos;드래그&amp;amp;드롭&apos;.&lt;/span&gt;&lt;/li&gt;
    &lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_hx&quot;&gt;
    &lt;h3 id=&quot;h1247469866936&quot;&gt;익숙한 에디터 사용하기.&lt;/h3&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_txt&quot;&gt;
    &lt;p&gt;새로운것은 언제나 불편하다는 사실을 잘 알고 있습니다. 텍스타일 에디터는 기존에 사용하던 도구들과 다른 환경을 제공하고 있기 때문에 처음에는 낮설고 불편할런지도 모릅니다. 실제로 텍스타일 에디터는 좋은 글쓰기를 위해 기존의 글쓰기 환경이 제공하던 많은 것들을 포기하고 있습니다. 풍부한 표현보다 구조적인 글쓰기에 집중할 수 있도록 유도하는 과정에서 할 수 없는 일들이 생겨나게 되었습니다. 하지만 여러분이 이 불편한 도구에 익숙해지기위해 작은 노력과 주의를 기울인다면 여러분의 글은 틀림없이 예전보다 더 좋아질 것입니다. &lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_img&quot;&gt;
    &lt;p&gt;&lt;img src=&quot;./modules/textyle/sample/ko/aboutTextyle5_1.gif&quot; id=&quot;xe_img_srl_11752&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_txt&quot;&gt;
    &lt;p&gt;여전히 텍스타일 에디터가 익숙하지 않는 분들께서는 관리자 환경의 &quot;설정 &amp;gt; 쓰기환경 설정 &amp;gt; 편집방식 설정&quot; 메뉴에서 &quot;기타 편집기&quot;를 선택 하세요. &apos;XpressEditor, FCKeditor, Xquared&apos; 와 같이 기존에 여러분들이 사용하시던 익숙한 오픈소스 에디터를 그대로 사용하실 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_hx&quot;&gt;
    &lt;h3 id=&quot;h1247460895830&quot;&gt;스킨 편집하기.&lt;/h3&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_txt&quot;&gt;
    &lt;p&gt;만약 여러분이 선택한 스킨이 컬럼 구조를 유지하고 있다면 화면의 좌우 배치를 쉽게 바꿀 수 있습니다. 모든 스킨이 이렇게 컬럼 형태를 유지하고 있는것은 아니기 때문에 손쉬운 스킨 조작 화면이 존재하는 것은 아니지만 간단하게 HTML 코드를 변경하는 것으로 가능하게 됩니다&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_img&quot;&gt;
    &lt;p&gt;&lt;img src=&quot;./modules/textyle/sample/ko/aboutTextyle6.gif&quot; id=&quot;xe_img_srl_11743&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;eArea xe_content xe_dr_txt&quot;&gt;
    &lt;p&gt;&quot;디자인 &amp;gt; HTML·CSS 편집 &amp;gt; HTML 편집&quot; 화면에서 두 번째 라인 &amp;lt;div id=&quot;container&quot; class=&quot;&lt;span style=&quot;font-weight: bold; text-decoration: underline;&quot;&gt;ce&lt;/span&gt;&quot;&amp;gt; 부분을 &amp;lt;div id=&quot;container&quot; class=&quot;&lt;span style=&quot;font-weight: bold; text-decoration: underline;&quot;&gt;ec&lt;/span&gt;&quot;&amp;gt; 으로 변경하시면 화면의 좌우 배치가 바뀝니다. 이러한 설정은 &apos;초기화&apos; 하거나 다른 스킨을 선택했을 때 사라집니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</content>
                  <category term="textyle"/>
            <category term="텍스타일"/>
            <category term="텍스타일에디터"/>
            <category term="글감수집기"/>
            
   </entry>
   <entry>
      <title>Basic Network, But very useful!!!!!</title>
      <id>http://www.textyle.kr/747</id>
      <published>2010-07-20T14:26:00+09:00</published>
      <updated>2010-07-20T14:26:00+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.textyle.kr/747"/>
      <link rel="replies" type="text/html" href="http://www.textyle.kr/747#comment"/>
      <author>
         <name>우와신난다</name>
                  <uri>http://alloe.tistory.com</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;br /&gt;

&lt;H2 id=header1&gt;Network의 기본&lt;/H2&gt;
&lt;P&gt;네트워크의 기본적인 사항에 대해 먼저 알아 보도록 하겠습니다.%%% 거의 인터넷 표준으로 자리잡은 TCP/IP에 대해서만 알아보도록 하겠습니다. 그러나 TCP/IP 주제만 가지고도 몇 개의 강좌를 해야 되므로, 자세한 내용은 다른 서적이나 강좌를 참고하세요.%%% 제가 추천하는 책은 &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;TCP/IP Illustrated, Volume 1 (W. Richard Stevens 저) 
&lt;LI&gt;TCP/IP Protocol Suite (Behrouz A, Forouzan 저) &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;를 추천합니다. 둘 다 원서입니다. 영어가 부담스러우신 분은 각 서적에 대한 번역서도 있으니 번역의 질 등을 잘 알아보고 선택하시기 바랍니다.%%% 다른 책을 참고하셔도 크게 상관은 없으나 간략한 소개만 되어 있는 것이 아닌 자세한 내용이 있는 것을 보세요. 왜냐하면 정확한 TCP/IP의 동작을 알아야지 네트워크에 오류가 있을 때 보다 쉽게 오류를 수정할 수 있기 때문입니다. &lt;/P&gt;
&lt;H3 id=header2&gt;클라이언트와 서버구조&lt;/H3&gt;
&lt;P&gt;대부분 네트워크 프로그램은 서버와 클라이언트로 구분할 수 있습니다. 두 개를 구분하는 기준은 그 역할이 무엇이냐 입니다. 그 기준을 간단히 설명하면 &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;서버 : 클라이언트가 어떤 작업의 요청이 들어오면 요청을 처리하고 그 결과를 클라이언트에게 알려 주는 역할 
&lt;LI&gt;클라이언트 : 서버에게 작업을 요청하고 그 작업의 결과를 받아서 보여주는 역할 &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;이렇게 설명할 수 있습니다.%%% 클라이언트/서버 구조는(이하 C/S) 우리 일상에도 많은 예가 있습니다. 가장 흔한 예가 웹 브라우저와 웹 서버입니다. 인터넷 익스플로러나 네스케이프가 클라이언트 역할을 하고 접속한 그리고 우리에게 서비스를 제공하는 컴퓨터가 서버라고 생각하시면 됩니다. 정확히는 아파치나 IIS 같은 http 서버를 말합니다. &lt;/P&gt;
&lt;P&gt;여기서 클라이언트와 서버의 차이는 클라이언트는 서버 하나와 통신을 하지만, 서버는 여러 개의 클라이언트를 상대합니다. 그래야만 더 많은 사용자들에게 서비스를 제공할 수 있습니다. &lt;/P&gt;
&lt;P&gt;그러나 모든 것이 C/S 구조로 된 것은 아닙니다. 클라이언트와 서버 역할을 모두 하는 것도 있습니다. P2P(Peer To Peer)가 그것입니다. 대표적인 소프트웨어로 소리바다나 구루구루 같은 것들이 여기에 속합니다. P2P는 클라이언트와 서버의 역할을 동시에 하고 있습니다.(여기에 대한 내용은 &lt;A class=con_link href=&quot;http://extremendl.net/&quot; target=_blank&gt;&lt;FONT color=#111188&gt;http://extremendl.net&lt;/FONT&gt;&lt;/A&gt; 에서 논의되고 있으니 참고하세요.) &lt;/P&gt;
&lt;H3 id=header3&gt;TCP/IP&lt;/H3&gt;
&lt;P&gt;TCP/IP 를 알아보기 전에 간단히 프로토콜(Protocol)의 정의에 대해서 알아보도록 하겠습니다. &lt;/P&gt;
&lt;P&gt;&quot;둘 이상의 통신 개체 사이에 교환되는 메시지의 형태, 의미, 전송 순서, 그리고 메시지 송수신 및 기타 사전에 수행할 동작을 정의한 규약&quot; &lt;/P&gt;
&lt;P&gt;두 개 이상의 호스트(컴퓨터) 사이에서 데이터를 약속에 의한 방법으로 주고 받자는 것입니다. TCP/IP 도 이런 프로토콜의 한 종류입니다. 보통 TCP/IP 라 부르지만 정확히는 TCP/IP 프로토콜 그룹(패밀리)라고 부릅니다. 그룹이므로 TCP와 IP 프로토콜만 있는 것은 아닙니다. TCP, UDP, ARP, RARP, ICMP 등 여러 가지가 같이 있는 프로토콜입니다. 여기에서 대표적인 프로토콜?TCP와 IP 이기 때문에 TCP/IP 라고 부릅니다. &lt;/P&gt;
&lt;P&gt;네트워크 프로토콜들은 대부분 계층(Layer)이라는 개념을 가지고 있습니다. 여기서 OSI 7 Layer 를 낯?드리고 싶지만, 이번 글은 소켓?련?글이므로 다른 서적이나 강좌를 참고하세요. 이것은 꼭 알아야 할 기본적인 네트워크 개념이니 꼭 익히셔야 합니다.%%% 계층의 개념을 간단히 말씀 드리면, 어떤 계층의 통신 상대의 같은 계층과 의미 있는 통신을 합니다. 그리고 각 계층들은 그 밑 계층이 제공하는 서비스를 이용하여 그 상위 계층에 서비스를 제공합니다. 만약 한 계층의 인터페이스가 변한다면, 그 바로 상위 계층에만 영향을 줍니다. 그리고 어느 한 계층에서 생성된 메시지들은 상대방의 같은 계층에서 분석되고 작동합니다. 무슨 말인지 조금 어렵게 느껴질 수 있습니다. &lt;/P&gt;
&lt;P&gt;1) 링크 계층 &lt;/P&gt;
&lt;P&gt;물리적인 인터페이스와 관련된 하드웨어적인 부분을 제어합니다. 운영체제와 디바이스 드라이버나 그와 관련된 랜카드, 그와 연결된 케이블 같은 것을 제어하는 계층을 말합니다. &lt;/P&gt;
&lt;P&gt;2) 네트워크 계층 &lt;/P&gt;
&lt;P&gt;네트워크상의 패킷의 이동을 제어하는 계층입니다. 패킷이라는 말이 처음 나왔는데, 패킷은 네트워크를 통해 데이터를 전달할 때 헤더와 데이터의 묶음을 말합니다. 정확히 이 계층에서는 IP 데이터그램이라고 합니다.(IP를 이용하여 신뢰성 없이 전달됩니다.) 이 패킷에는 송/수신지의 정보가 포함되어 있습니다. 이 계층의 역할은 한마디로 우편물의 주소와 같습니다. 어느 곳에 편지를 보낸다고 할 때, 여러 우체국을 거쳐 목적지의 우편함까지 옵니다. 우편물을 패킷이라면 우체국들은 라우터나, 게이트웨이라고 할 수 있습니다. 패킷이 가려고 하는 호스트(컴퓨터)까지의 이동을 담당하는 곳이 네트워크 계층입니다. 주로 IP가 이 역할을 하는데 IP는 신뢰성이 보장되지 않습니다. 확실히 갔는지 아닌지 알 수 없습니다. 또 다른 기능들이 많이 숨어 있는 계층이지만 여기까지 하도록 하겠습니다. &lt;/P&gt;
&lt;P&gt;3) 트랜스포트 계층 &lt;/P&gt;
&lt;P&gt;상위 응용 층에 대해 두 호스트간의 데이터 흐름을 제공합니다. TCP/IP 에는 TCP 와 UDP라는 트랜스포트 프로토콜이 있습니다. &lt;/P&gt;
&lt;P&gt;TCP는 위의 상위계층이 준 데이터를 목적지로 전달과 흐름제어의 기능을 제공합니다. 흐름의 제어란 데이터를 언제 보내야 하는지 얼마큼의 크기로 보내야 하는지 어떤 것을 보내야 하는지를 제어한다고 간단히 생각해도 될 것 같습니다. 위의 네트워크 계층에서 우편물과 같아 잘 보내어 졌는지 잘 받았는지 확인할 길이 없다고 했습니다. 그러나 TCP는 이러한 것까지 알아서 해줍니다. 즉 전화라고 보시면 됩니다. 우리가 타인에게 전화를 걸면, 신호음이 가고 상대편이 받을 때까지 기다립니다. 만약 상대방이 받지 않는다면, 우리는 다시 전화를 걸 수 있습니다. TCP도 마찬가지 입니다. 보내고 잘 받지 못했다면 다시 보내는 것이죠. TCP 는 네트워크 계층의 상위계층입니다. 이전 Layer 를 설명할 때, 하위계층의 인터페이스를 이용한다고 했습니다. 즉. TCP도 IP 데이터그램을 이용하여 정보가 전달 되는 것입니다. 그래서 패킷만 두고 본다면, TCP도 신뢰성이 없습니다. 그러나. IP의 상위 계층인 TCP는 이러한 점을 보안하여 서비스를 해줍니다. 즉, “시간이 얼마나 지났는데 와야 할 패킷이 안 온다 무언가 문제가 있다.” 이런 식으로 보안합니다. TCP는 연결지향 서비스이고 두 호스트간의 신뢰성 높은 데이터 흐름을 제공합니다. 연결지향이라는 말은 TCP는 데이터를 주고 받기 전에 클라이언트와 서버가 이제 연결해서 데이터를 주고 받겠다는 약속을 하는 것입니다. 그리고 데이터를 보내면 그 데이터가 반드시 목적지에 도착하고, (일정 시간 내에 받지 못하면 패킷이 손실 되었다고 보고, 다시 보내달라고 요청을 합니다.) 보낸 순서 또한 똑같다는 것입니다. TCP로 보내는 패킷을 TCP 세그먼트(segment)라고 보통 부릅니다. &lt;/P&gt;
&lt;P&gt;UDP는 비연결형 서비스입니다. 즉, 클라이언트와 서버가 연결 약속은 하지 않고 바로 데이터를 주고 받는다는 것을 말합니다. 그리고 신뢰성이 없습니다. 즉, 데이터가 목적지에 반드시 도착하리라는 보장이 없습니다. 물론 보낸 순서도 마찬가지입니다. UDP로 보내는 패킷을 UDP 데이터그램(datagram)이라고 부릅니다.%%% 주로 TCP를 사용하기는 합니다만 UDP도 쓰이는 곳도 많습니다. UDP가 속도가 비교적 빠르기 때문에 패킷 하나 없어져도 크게 관계없는 실시간 방송이 라던지 그런 곳에 쓰입니다. 요즘 게임에도 TCP 와 UDP를 같이 섞어서 많이 사용한다고 합니다. &lt;/P&gt;
&lt;P&gt;예를 들어 TCP와 UDP를 조금 더 알아 봅시다. 만약 서버에서 3개의 패킷을 보낸다고 가정을 한다면 여러 가지 라우터나 게이트웨이들은 패킷의 IP를 보고 이 패킷의 경로를 정해 목적지까지 보내 줍니다. 3개의 패킷은 가는 도중의 네트워크의 상태에 따라서 다른 경로를 통해 전달 될 수도 있습니다. 1번 패킷이 도중에 손실되고 3번이 2번 보다 먼저 목적지에 도착할 수도 있습니다. 만약 TCP 연결이라면 1번이 도착하지 않았으므로 다시 1번을 보내달라고 하고 서버는 다시 1번부터 3번까지 보내 줍니다. 여기서 1번만 보낼 수도 있지만 알고리즘이 복잡하고 네트워크가 충분히 빠르므로 1, 2, 3을 모두 보냅니다. 그런데 UDP는 3, 2번 패킷을 그대로 받습니다. 1번이 있는 지도 모릅니다. 그냥 받은 대로 쓰는 것입니다. 그런 특성들은 프로그래머들이 짜는 응용 계층에서 별도로 처리를 해주어야 합니다. &lt;/P&gt;
&lt;P&gt;4) 응용 계층 &lt;/P&gt;
&lt;P&gt;간단히 우리가 쓰는 네트워크 응용 프로그램을 말합니다. &lt;/P&gt;
&lt;H3 id=header4&gt;IP&lt;/H3&gt;
&lt;P&gt;IP는 인터넷상의 고유의 주소입니다. 전세계에서 유일합니다. 4바이트(32비트)의 숫자로 구성된 주소입니다. 랜카드와 1:1로 대응 됩니다. 예를 들면 104.245.123.24과 같은 식으로 되어있습니다. 이런 표시 방식을 dotted-decimal 방식이라고 합니다. 사람이 알기 쉽게 이런 식으로 쓰는 것입니다. 실제로는 11010100110... 이런 식으로 되어야 컴퓨터가 알아 볼 수 있습니다. IP는 클래스 A, 클래스 B, 클래스 C, 클래스 D, 클래스 E 가 있습니다. &lt;/P&gt;&lt;PRE&gt;클래스     | 범위
A 클래스  | 0.0.0.0 - 127.255.255.255
B 클래스  | 128.0.0.0 - 191.255.255.255
C 클래스  | 192.0.0.0 - 233.255.255.255
D 클래스  | 224.0.0.0 - 239.255.255.255
E 클래스  | 240.0.0.0 - 255.255.255.255
&lt;/PRE&gt;
&lt;P&gt;각 클래스들은 이런 범위를 가지고 있습니다. 클래스 E는 나중을 위해 예약되어 있는 클래스 입니다. 클래스 D는 멀티캐스트를 위한 IP입니다. 한마디로 우편물이 가기 위한 자신의 집의 주소라고 보시면 됩니다. &lt;/P&gt;
&lt;H3 id=header5&gt;도메인 주소&lt;/H3&gt;
&lt;P&gt;컴퓨터는 IP를 인식하지만 사람이 외우기는 조금 불편합니다. 그래서 도메인 주소라는 것을 사용합니다. bgda.org 이런 식으로 쓰면 사람이 보다 알기겠지요. 컴퓨터는 도메인이 입력되어 들어오면, 그 도메인에 대항하는 IP로 변환해서 사용합니다. 이런 서비스를 DNS (Domain Name Service) 라고 합니다. &lt;/P&gt;
&lt;H3 id=header6&gt;Port&lt;/H3&gt;
&lt;P&gt;포트(Port)는 하나의 컴퓨터에 실행 중인 여러 네트워크 프로그램을 구분하기 위해 부여된 번호입니다. 16비트로 구성된 번호입니다. 즉, 우편물이 집에 도착했는데 그 우편물이 누구의 것이냐는 것입니다. 여기서 집을 하나의 컴퓨터(호스트)라 하고, 주소를 컴퓨터의 IP, 우편물에 적힌 이름은 포트 번호라고 이해하시면 쉬울 것입니다. 즉, 컴퓨터까지는 왔는데 그 컴퓨터의 어느 프로그램이 패킷을 받을지를 알아야 하니 이런 번호가 부여됩니다.%%% 우리가 자주 쓰는 웹 서버나 ftp 서버 같은 것들도 전부 포트번호가 있습니다. 그런데 이런 것들은 자주 많이 쓰이기 때문에 포트번호를 지정해 놓았습니다. 그래서 우리들은 인터넷 주소만 입력하면 바로 웹 페이지를 열 수 있는 것입니다. 포트 번호를 따로 적지는 않습니다. 왜냐하면, 미리 이 포트번호는 http의 번호이다라고 정해놓았기 때문입니다. 그렇게 많이 쓰는 서버들의 포트들을 well-known 포트라고 합니다. 1 - 1024까지는 well-known 포트로 되어있습니다. 그래서 보통 새로운 서버를 만든다면 이 포트(well-know port)는 되도록 피하는 것이 좋습니다. 포트 번호가 16비트니 포트번호는 충분할 것입니다. &lt;/P&gt;
&lt;H3 id=header7&gt;루프백(loopback)&lt;/H3&gt;
&lt;P&gt;클라이언트와 서버가 같은 호스트에서 TCP/IP를 이용하여 서로 통신할 수 있도록 하는 것입니다. 127.0.0.1 - 127.255.255.255 까지가 루프백 주소로써 localhost라는 이름으로도 할당하고 있습니다. 루프백으로 보내어진 데이터는 밖으로는 보내어지지 않습니다. 그러나 브로드캐스트나 멀티캐스트주소로 보내어진 것은 루프백에 복사된 다음 밖으로 나가게 됩니다. 그리고 자신의 IP로 보내어진 것도 루프백으로 보내어집니다. &lt;/P&gt;
&lt;H3 id=header8&gt;MTU&lt;/H3&gt;
&lt;P&gt;MTU(Maximum Transmission Unit) 최대 전송단위라는 것인데 대부분의 네트워크는 패킷의 상한선이 정해져 있습니다. 그것보다 많은 양은 그보다 작게 쪼개어서 보냅니다. 이런 것을 단편화(Fragmentation)라고 합니다. 단편화된 패킷은 받을 때 합쳐지게 됩니다. &lt;/P&gt;
&lt;H3 id=header9&gt;Path MTU&lt;/H3&gt;
&lt;P&gt;두 호스트의 네트워크는 다를 수 있습니다. 즉, 누구는 LAN이고 누구는 전화선일 수도 있는 겁니다. 그때 두 네트워크의 MTU는 다릅니다. 그리고 두 호스트 사이에 어떠한 네트워크도 있을 수 있습니다. 이 두 호스트 사이에 패킷을 전송하는 링크상의 최소 MTU 크기가 Path MTU라 합니다. 만약에 A 와 D가 통신을 한다고 하면 A와 D사이에는 B, C 라는 네트워크가 있다고 해봅시다. &lt;/P&gt;
&lt;P&gt;A - B - C - D &lt;/P&gt;
&lt;P&gt;A의 MTU가 100 B 200 C 70 D 80이라는 MTU를 가지고 있다면 A와 D의 Path MTU는 70이 되는 것입니다. &lt;/P&gt;
&lt;H3 id=header10&gt;TTL&lt;/H3&gt;
&lt;P&gt;Time-to-live 라는 것으로 패킷이 통과할 수 있는 라우터의 수를 제한하기 위해 사용됩니다. 하나의 라우터를 거칠 때마다 TTL 값이 1씩 줄어들어 0이 되면 패킷은 버려지게(삭제) 됩니다. 라우터를 많이 안거치는 로컬에서는 작아도 상관없지만, 외국이나 그런 먼 곳(거쳐야 할 라우터가 많은) 곳에 보내려면 TTL값은 충분히 커야 합니다. 그렇지 않으면, 가는 도중에 TTL값이 0이 되어 패킷이 삭제될 수 있습니다. 라우터는 두 개의 같은 네트워크를 연결하는 중간 다리 역할을 하는 것이라고 보시면 됩니다. 게이트웨이란 것도 있는데, 이것은 서로 다은 네트워크를 연결하는 역할을 한다고 보시면 됩니다. &lt;/P&gt;
&lt;H3 id=header11&gt;TCP 연결 (Three-way Handshake)&lt;/H3&gt;
&lt;P&gt;위에서 TCP는 연결지향 서비스라고 했습니다. TCP 연결 설정은 다음의 시나리오로 이루어 집니다. &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;서버는 들어오는 연결을 받을 준비가 되어 있도록 준비되어야 합니다. 
&lt;LI&gt;클라이언트가 접속을 요청합니다. (클라이언트가 서버에게 SYN 세그먼트를 보냄) 
&lt;LI&gt;서버는 클라이언트의 SYN 도착을 클라이언트에게 알립니다. (서버가 클라이언트에게 SYN을 보냄) 
&lt;LI&gt;클라이언트는 서버에게 SYN도착을 알림(클라이언트가 서버에게 ack를 보냄) &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;이때 교환하는 패킷이 3개인데 그래서 Three-way Handshake 라 합니다. 쉽게 말해서 클라이언트가 서버에게 “접속한다.” 그러면 서버는 “그래 접속해라.” 합니다. 그리고 클라이언트는 “알았다.” 라고 하고 접속이 완료 되는 겁니다. &lt;/P&gt;
&lt;H3 id=header12&gt;TCP 연결 종료&lt;/H3&gt;
&lt;P&gt;다음과 같은 시나리오 입니다. &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;클라이언트에서 close를 호출하면 데이터를 그만 보내겠다는 FIN 세그먼트를 서버에 보냅니다. 
&lt;LI&gt;서버가 FIN을 받으면 FIN을 받았다는 ack를 클라이언트에게 보내고 close가 호출됩니다. 
&lt;LI&gt;그러면 서버도 FIN을 클라이언트에게 보내게 됩니다. 
&lt;LI&gt;그러면 마지막으로 클라이언트는 FIN을 받고 ack를 서버에게 보냅니다. &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;여기서는 클라이언트가 close를 먼저 했는데. 서버가 먼저 할 수도 있습니다. &lt;/P&gt;
&lt;H2 id=header13&gt;소켓 API&lt;/H2&gt;
&lt;P&gt;이 글에 있는 소스는 TCP/IP 소켓프로그래밍 version C &amp;lt;사이텍미디어&amp;gt;를 참고 하였음을 알려드립니다. &lt;/P&gt;
&lt;H3 id=header14&gt;소켓 API란?&lt;/H3&gt;
&lt;P&gt;네트워크 상에서 호스트간에 통신을 가능하게 해주는 일반적인 인터페이스 입니다. 응용층과 트랜스포트 계층 사이의 중간에 위치해있습니다. &lt;/P&gt;
&lt;H3 id=header15&gt;소켓 주소 구조&lt;/H3&gt;
&lt;P&gt;소켓 API는 소켓과 관련된 주소를 지정하기 위해 일반적인 소켓 구조체를 정의해 놓았습니다.(소켓 주소에는 TCP/IP를 위한 주소만 있는 것이 아니라 다양하게 많이 존재합니다.) 그 형태는 &lt;/P&gt;&lt;PRE&gt;struct sockaddr
{
    unsigned short sa_family; /* Address family */
    char sa_data[14]; /* Family-specific address */
};
&lt;/PRE&gt;
&lt;P&gt;이렇게 생겼습니다. 실제 TCP/IP 소켓 주소를 지정할 때는 이 구조체를 사용하지 않습니다. TCP/IP에 맞추어 사용합니다. TCP/IP 소켓 주소를 위해 사용하는 구조체를 보면, &lt;/P&gt;&lt;PRE&gt;struct in_addr
{
    unsigned long s_addr;
};

struct sockaddr_in
{
    unsigned short sin_family;
    unsigned short sin_port;
    struct in_addr sin_addr;
    char sin_zero[8];
};
&lt;/PRE&gt;
&lt;P&gt;sockaddr_in의 sin_family 인자는 인터넷 주소 패밀리입니다. 이번 강좌에서는 AF_INET를 사용합니다. (일단 이렇게만 알아두세요.) 이건 IPv4 프로토콜이라는 것을 말합니다. sin_port 는 포트 번호를 지정하는 것입니다. short니 2바이트, 16비트 정수입니다. sin_addr은 IP주소가 들어 가는 부분입니다. 위에 struct in_addr의 정의가 나와있습니다. 정의에서 나오는 것과 같이 여기에는 IP의 32비트 주소가 들어 갑니다. 그러니 &quot;128,23,23,14&quot; 이런 문자열이 들어가진 않습니다. 이걸 110010101.. 이런 식으로 변환하여 넣어 주어야 합니다. 두 개를 변환하는 함수 물론 있습니다. 그리고 그 다음이 sin_zero&lt;SUP&gt;&lt;A id=footnoteref8 class=con_link href=&quot;http://www.gpgstudy.com/gpgiki/%EC%86%8C%EC%BC%93%20%EA%B0%95%EC%A2%8C#footnote8&quot; target=_blank&gt;&lt;FONT color=#114b66&gt;[8]&lt;/FONT&gt;&lt;/A&gt;&lt;/SUP&gt; 이 부분인데 여기에는 0값이 들어 갑니다. 즉, 사용하지 않습니다. 사용하지 않는데 왜 여기에 있는가 하면, 앞에 일반적인 구조체를 보여 드렸습니다. 그것의 크기에 맞추어서 8바이트 더미 값이 들어가 있습니다. &lt;/P&gt;
&lt;H3 id=header16&gt;바이트 순서(Byte Ordering)&lt;/H3&gt;
&lt;P&gt;컴퓨터 메모리에 데이터가 저장되는 순서를 말합니다. 이것은 수행되는 기계에(CPU) 의존됩니다. 여기에는 Little-Endian 과 Big-Endian이 있습니다. Little-Endian 은 가장 낮은 바이트부터 저장되고 Big-Endian은 가장 높은 바이트부터 저장됩니다. 그림을 보면 쉽게 이해가 가실 겁니다. 4바이트 정수를 저장한다고 하면, &lt;/P&gt;&lt;PRE&gt;|   1byte   |
+-----------+-----------+-----------+-----------+
|    1      |    2      |    3      |    4      |
+-----------+-----------+-----------+-----------+

|   1byte   |
+-----------+-----------+-----------+-----------+
|    4      |    3      |    2      |    1      |
+-----------+-----------+-----------+-----------+
   addr A     addr A+1     addr A+2    addr A+3
&lt;/PRE&gt;
&lt;P&gt;위에 것이 Little-Endian 밑에 그림이 Big-Endian 입니다. Little-Endian 방식에 대표적인 것이 Intel계열의 CPU이고 Big-Endian은 Sparc 계열의 CPU입니다. 같은 기종의 통신이면 바이트 순서는 중요하지 않지만, 서로 다른 기종의 통신이라면 중요해 집니다. 통신을 할 때는 Big-Endian을 따릅니다. 그래서 네트워크로 보내기 전에 이 바이트 순서를 조정해 주어서 보내어야만 합니다.%%% 그럼 네트워크 순서와 호스트 순서를 바꾸는 함수에 대해서 알아 보도록 하겠습니다. 함수 이름에는 규칙이 있는데, &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;h - host 
&lt;LI&gt;n - network 
&lt;LI&gt;l - long 
&lt;LI&gt;s - short &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;이렇습니다. 예를 하나 들면, &lt;/P&gt;&lt;PRE&gt;long int htonl (long int hostLong);
&lt;/PRE&gt;
&lt;P&gt;무슨 말일까요? 함수 이름이 htonl 입니다. 호스트에서 네트워크로 바꾸라는 얘기입니다. type은 long 형이고요. 이렇게 각각 long와 short에 대해 함수가 있습니다. &lt;/P&gt;&lt;PRE&gt;long int htonl (long int hostLong);
long int ntohl (long int netLong);

short int htons (short int hostShort);
short int ntohs (short int netShort);
&lt;/PRE&gt;
&lt;P&gt;사용의 예를 들어 보죠. 포트번호가 2바이트입니다. 이것을 네트워크로 보내기 위해서는 바이트 순서를 조정해야 합니다. 소켓 주소 구조체에 대입은 &lt;/P&gt;&lt;PRE&gt;SocketAddress.sin_port = htons(appPort);
&lt;/PRE&gt;
&lt;P&gt;이렇게 합니다. &lt;/P&gt;
&lt;H3 id=header17&gt;소켓기술자란?&lt;/H3&gt;
&lt;P&gt;소켓 기술자는 유닉스의 파일 기술자와 동일합니다. 다만 그 I/O가 네트워크일 뿐입니다. 쉽게 말해 컴퓨터에서 네트워크로 나가는 문의 고유번호라고 생각하시면 됩니다. 네트워크로 데이터를 보내거나 받으려면 커널에게 소켓을 만들어 달라고 요청을 합니다. 그럼 커널은 소켓 하나를 열고 우리에게 그 소켓의 고유번호를 줍니다. 그것이 소켓 기술자입니다. 유닉스의 파일기술자에 대해 잘 아신다면, 똑같다고 보면 이해가 빠르실 겁니다. 이제부터 소켓번호라고 하면 이 소켓 기술자를 얘기하는 것으로 하겠습니다. &lt;/P&gt;
&lt;H3 id=header18&gt;TCP 소켓&lt;/H3&gt;
&lt;P&gt;이제 TCP 서버와 클라이언트의 기본적인 함수 호출 구조를 살펴 보도록 하겠습니다. &lt;/P&gt;
&lt;P&gt;서버 : socket() -&amp;gt; bind() -&amp;gt; listen() -&amp;gt; accept() -&amp;gt; send()/recv() &lt;/P&gt;
&lt;P&gt;서버가 여기까지 호출을 하게 되면 클라이언트의 접속이 들어 오는지 기다립니다. &lt;/P&gt;
&lt;P&gt;클라이언트 : socket() -&amp;gt; connect() -&amp;gt; send()/recv() &lt;/P&gt;
&lt;P&gt;여기서 클라이언트와 서버는 three-way handshake를 하여 연결을 합니다. 그 후에 서버와 클라이언트는 send()와 recv() 를 이용해 데이터를 주고 받습니다. 그리고 close() 함수를 호출하여 접속을 끊게 되는 것입니다. &lt;/P&gt;
&lt;P&gt;그럼 서버와 클라이언트에서 공통으로 사용하는 소켓 생성과 소멸에 관련된 함수에 대해서 알아 보도록 하겠습니다. 그 전에 여기서 설명하는 함수는 다른 말이 없으면 리턴 값이 에러면 -1을 리턴하고 errno이라는 전역변수에 에러 값을 넣어줍니다. 이 errno의 값을 보고 무슨 에러가 났는지 알 수 있습니다. &lt;/P&gt;&lt;PRE&gt;int socket( int protocolFamily, int type, int protocol );
&lt;/PRE&gt;
&lt;P&gt;socket 함수의 역할은 커널에 소켓을 열어 달라고 요청을 하여 그 소켓번호를 우리에게 넘겨 줍니다. protocolFamily는 AF_INET를 씁니다. IPv4 protocol 을 사용한다는 것을 알리는 것입니다. 물론 다른 것도 있지만 이 글에는 이것만 씁니다. type은 TCP를 사용할 땐 SOCK_STREAM, UDP를 사용할 땐 SOCK_DGRAM 을 넣어서 어떤 서비스를 사용하는지 커널에 알려 줍니다. protocol은 raw소켓을 쓸 때 말고는 0을 설정합니다. 그러니 여기서는 항상 0을 사용할 것입니다.(IPPROTO_TCP, IPPROTO_UDP를 이용하셔도 됩니다.) raw소켓은 IP계층의 서비스를 직접 이용할 때 쓰는 것입니다. &lt;/P&gt;&lt;PRE&gt;int close( int sockfd );
&lt;/PRE&gt;
&lt;P&gt;소켓을 닫고 통신을 종료합니다. sockfd는 닫을 소켓 번호입니다. 성공하면 0을 실패하면 -1을 반환합니다. 닫힌 소켓은 더 이상 사용할 수 없습니다. 여기선 TCP를 설명하니 TCP에 대해 조금 더 설명하겠습니다. 내부적으로 TCP는 send buffer 와 recv buffer가 있습니다. 만약에 close를 호출 하였는데 send buffer에 보낼 데이터가 남아 있으면 그것을 모두 보낸 후에 앞서 설명 드린 TCP 연결 종료 절차를 따릅니다. &lt;/P&gt;
&lt;P&gt;위 두 함수에는 좀더 볼 것이 있는데. 그것은 참조 카운터입니다. socket로 소켓을 열면 참조 카운터가 1 증가 합니다. 그리고 다른 자식 프로세스로 복사될 때도 참조 카운터가 1증가 합니다. close는 참조 카운터를 1감소 시킵니다. 그러다가 참조카운터가 0이 되면 소켓을 닫습니다. 소켓 참조 카운터가 0이 아니라면 그것은 열린 상태가 되는 것입니다. &lt;/P&gt;&lt;PRE&gt;int shutdown( int sockfd, int howto );
&lt;/PRE&gt;
&lt;P&gt;이 함수도 네트워크 연결을 종료시키는 데 사용합니다. close()와 다른 점은 close는 참조 카운터를 1감소시키고 참조 카운터가 0이 되면 종료하는데 shutdown()은 참조 카운터와 상관없이 TCP의 연결 종료 절차를 시작합니다. 그런데 close()함수는 양방향(send recv) 둘 다 종료시키는데 반해 shutdown함수는 howto인자에 따라 동작이 달라집니다. 위에서 close함수를 설명할 때 약점이 하나 있었습니다. close()호출 후에 받을 데이터가 있다면 어떻게 할까요? 그건 받을 수 없습니다. 그러나 shutdown의 howto 인자를 설정하면 그것이 가능합니다. 그 값에는 다음과 같은 것이 있습니다. &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;SHUT_RD : 연결의 recv 한쪽만 닫습니다. 이제 이 소켓으로는 데이터를 받을 수 없습니다. 그리고 recv buffer도 폐기됩니다. 
&lt;LI&gt;SHUT_WR : 연결의 send 한쪽만 닫습니다. 이제 이 소켓으로는 어떤 데이터도 보낼 수 없게 됩니다.send buffer에 남아 있는 데이터는 모두 보낸 뒤에 TCP 연결 종료 절차가 뒤따릅니다. 
&lt;LI&gt;SHUT_RDWR : 연결의 양쪽 다 받습니다. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;만약에 자신은 데이터를 다 보냈다 하면, SHUT_WR인자를 설정하여 shutdown()을 호출하면 다른 쪽이 보내는 데이터를 받을 수 있게 되는 것입니다. &lt;/P&gt;
&lt;P&gt;이제는 TCP 서버의 기본적인 함수에 대해서 알아 보도록 하겠습니다. &lt;/P&gt;
&lt;P&gt;TCP 서버는 통신의 종단에서 클라이언트의 연결요구를 수동적으로 기다리는 역할을 합니다. 그럼 그 과정을 요약하면, &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;socket() 함수로 소켓을 생성 
&lt;LI&gt;bind() 함수로 생성된 소켓에 포트번호를 연결 
&lt;LI&gt;listen() 함수를 이용해 클라이언트의 연결요구를 받도록 함 
&lt;LI&gt;클라이언트의 연결요청이 들어오면 accept() 함수로 새로운 소켓을 얻음 
&lt;LI&gt;send() recv()를 사용하여 클라이언트와 통신 
&lt;LI&gt;서비스가 끝나면 close()함수를 이용하여 클라이언트의 연결을 닫음 &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;이제 여기에 관련된 함수에 대해 알아 보겠습니다. &lt;/P&gt;
&lt;P&gt;&lt;EM&gt;bind ()&lt;/EM&gt; &lt;/P&gt;&lt;PRE&gt;int bind( int sockfd,
          struct sockaddr * localAddress,
          unsigned int addressLen );
&lt;/PRE&gt;
&lt;P&gt;bind() 함수의 원형입니다. bind함수는 localAddress 변수에 있는 IP 주소와 Port 번호를 연결시켜 주는 역할을 합니다. 만약, 클라이언트(ip 123.145.234.1 포트 6000)가 ip 203.229.234.13 port 5000 번으로 접속을 요청해 왔다고 합시다. 그럼 서버는 그 ip와 포트 변호를 보고 어느 프로그램의 패킷인지를 알 수 있어야 합니다. 바로 그것을 알려 주는 그리고 명시 하는 함수가 바로 bind입니다. 그런데 서버는 여러 개의 클라이언트를 처리 한다고 했습니다. 클라이언트는 똑같은 IP와 포트 번호를 이용해서 (사실 IP는 다를 수 있습니다.) 접속을 해올 것입니다. 그 예를 설명해 보죠.%%% A 라는 서버에 x y라는 두 개의 클라이언트가 접속을 해왔다고 합시다. &lt;/P&gt;
&lt;P&gt;서버의 IP 는 111.222.333.44 Port 5000%%% x클라이언트 IP 222.222.222.22 Port 6000%%% y클라이언트 IP 222.222.222.33 Port 7000%%% 이라고 가정하면, &lt;/P&gt;
&lt;P&gt;x가 먼저 클라이언트에게 접속을 하고 y가 접속을 합니다. 그러면 TCP는 연결을 위해 소켓이 새로이 생성되는데 그곳에 socket pair이라는 구조체에 서버의 IP와 Port 클라이언트의 IP와 Port를 같이 저장합니다. 그러면 두 개의 x, y클라이언트가 구분이 되겠죠?%%% 이렇게 클라이언트와 서버 IP, Port를 모두 사용하여 구분한다고 생각하시면 됩니다. 그리고 아까 서버의 IP가 다를 수 있다고 했는데 그것은 하나의 컴퓨터에 하나의 IP. 즉, 하나의 네트워크 인터페이스(랜카드) 만이 있는 것은 아닙니다. IP는 인터페이스당 유일하게 하나입니다. 그럼 만약에 서버가 2개의 인터페이스를 가지고 있다면 서버 프로그래밍의 설정에 따라서 동시에 두 IP에서 오는 패킷을 받을 수 있습니다.%%% 나중에 서버 프로그래밍 예제를 보시면 나옵니다. INADDR_ANY 를 서버설정에서 IP부분에 설정을 하면 모든 인터페이스로부터 패킷을 받는다는 의미입니다. 물론 특정 인터페이스에서 오는 것만 받을 수도 있습니다. 그때 서버를 bind할 때 그 받을 IP만 지정하면 되는 것입니다. &lt;/P&gt;
&lt;P&gt;&lt;EM&gt;listen()&lt;/EM&gt; &lt;/P&gt;&lt;PRE&gt;int listen ( int socket, int backlog );
&lt;/PRE&gt;
&lt;P&gt;첫 번째 인자는 소켓 번호입니다. 두 번째 인자가 설명이 조금 필요한데, 간단히 설명하면 연결요구 개수의 최대값을 나타냅니다. 무슨 말이신지 이해가 잘 안되실 수도 있는데 조금 더 설명을 드리면, TCP가 접속을 할 때 three-way handshake를 한다고 했습니다. 이 도중에 또 다른 클라이언트가 접속을 요구 할 수도 있습니다. 그럼 어떻게 해야 할까요? 일단 어디에다 저장해두어서 지금 하고 있는 연결설정을 끝내고 차례대로 들어온 순서대로 연결 설정을 해주면 되겠지요? 그 저장해둘 클라이언트 연결 요구의 수를 말하는 것입니다. 내부적으로는 연결이 완료된 것 대기중인 것 이렇게 두 개의 큐가 있습니다. 이 큐는 FIFO(First In First Out) 로 동작합니다. 연결완료 된 것과 대기중인 것 모두 합친 것의 수입니다.%%% 만약에 그 대기수도 다 차있는 상태에서 다시 연결 요구가 들어 오면 어떻게 할까요? TCP는 거기에 대해서 아무 것도 안 합니다. 그럼 클라이언트는 아무 응답이 없으므로 일정 시간 뒤에 다시 연결 요구를 합니다. 예전에는 이 수는 5 를 사용했던 것 같습니다. 많은 예제들이 아직도 5를 사용하고 있는데, 5 라고 해서 꼭 5개만 되는 것은 아닙니다. 운영체제나 네트워크 인터페이스 드라이브에 따라서 다를 수 있습니다. 어떤 것은 입력된 값 그대로 쓰고 어떤 건 여기에다가 1.5를 곱한 수를 사용하는 등 다양합니다. 그리고 이제 5 라는 제한도 없어 졌습니다. 더 큰 수도 지원합니다. 만약에 운영체제에서 지원하는 수보다 더 큰 수를 넣는다면 어떻게 될까요? 그렇게 해도 운영체제가 알아서 최대값을 안 넘게 해준다고 합니다. &lt;/P&gt;
&lt;P&gt;&lt;EM&gt;accept()&lt;/EM&gt; &lt;/P&gt;&lt;PRE&gt;int accept( int socket,
            struct socket * clientAddress, u
            nsigned int * addressLen );
&lt;/PRE&gt;
&lt;P&gt;이 함수의 기능은 listen 함수가 연결 요구의 개수를 지정하고 내부 큐에는 연결 설정이(three-way handshake) 완료된 큐와 대기중인 큐 두 개가 있다고 했습니다. 그 완료된 큐에서 순서대로(FIFO) 하나 가져와서 상대방과 연결된 하나의 소켓을 만드는 역할을 합니다. 만약에 완료된 큐에 아무것도 없다면 생길 때까지 블록 됩니다.%%% 함수가 성공하면 새롭게 생성된 소켓 번호를 리턴 합니다. 이 소켓을 통해 클라이언트와 통신을 합니다. &lt;/P&gt;
&lt;P&gt;&lt;EM&gt;send()/recv()&lt;/EM&gt; &lt;/P&gt;&lt;PRE&gt;int send( int socket, const void * msg,
          unsigned int msgLength, int flag );
int recv( int socket, void * recvBuffer,
          unsigned int bufferLength, int flag );
&lt;/PRE&gt;
&lt;P&gt;이 함수들은 이름 그대로 데이터를 주고 받는 함수입니다. send 함수의 socket 인자는 보낼 곳의 소켓번호이고, msg는 보낼 메시지의 시작 포인터입니다. msgLength 는 보낼 메시지의 길이입니다. recv 함수의 socket 인자는 send 함수와 동일합니다. recvBuffer은 받을 버퍼의 시작 포인터이고, bufferLength는 해당 버퍼의 크기입니다. Send 함수의 리턴 값은 보낸 데이터의 byte수입니다. 그리고 recv 함수의 리턴 값은 recvBuffer에 넣은 데이터의 수를 리턴 합니다. 만약 상대방이 접속을 끊으면 recv 함수의 리턴 값은 0이 됩니다.%%% TCP에서 데이터를 주고 받을 때 잊지 말아야 할 중요한 것이 있습니다. 예를 들어 설명을 하면, 데이터 100바이트를 보내겠다고 가정합시다. &lt;/P&gt;&lt;PRE&gt;send( socket, buffer, 100, 0 );
&lt;/PRE&gt;
&lt;P&gt;이런 식으로 보내게 됩니다. 그런데 send함수는 100바이트 전부를 보낼 때까지 블록 됩니다.(blocking mode 일 때) 그리고 send로 보낸 데이터를 받을 때는 recv함수를 사용합니다. 받을 버퍼로 char buffer&lt;SUP&gt;&lt;A id=footnoteref512 class=con_link href=&quot;http://www.gpgstudy.com/gpgiki/%EC%86%8C%EC%BC%93%20%EA%B0%95%EC%A2%8C#footnote512&quot; target=_blank&gt;&lt;FONT color=#114b66&gt;[512]&lt;/FONT&gt;&lt;/A&gt;&lt;/SUP&gt;를 선언했다고 하지요. &lt;/P&gt;&lt;PRE&gt;recv( socket, buffer, 512, 0 );
&lt;/PRE&gt;
&lt;P&gt;그런데 이 recv함수는 우리가 원하는 데이터의 양만큼 데이터를 받지 못합니다. 내부적으로 TCP는 보내는 버퍼와 받는 버퍼 두 개가 있다고 했습니다. send 함수는 보내는 버퍼에 보낼 데이터를 옮기고 리턴 됩니다. recv 함수는 받는 버퍼에 1바이트라도 있으면 그것을 가져옵니다. 우리가 512 바이트를 선언하고 512를 인자로 넘겨 512바이트 이상은 가져 오지 않습니다. blocking mode일 때 recv 함수는 받는 버퍼가 비어 있으면 데이터가 들어올 때까지 기다렸다가 들어오면 그것을 받아서 리턴 합니다. 즉, 우리가 받기를 원하는 만큼 받을 수 없다는 것입니다. recv 해서 받을 데이터의 양은 아무도 알 수 없습니다. 그래서 항상 리턴 값을 체크해서 얼마나 받았는지 확인을 해야 하는 것입니다.%%% 그리고 TCP는 stream 방식입니다. 클라이언트에서 100바이트와 50바이트 250바이트를 이렇게 3번을 보냈다고 합시다. 그런데 이 데이터들을 구분할 수가 없다는 것입니다. 그것을 구분하는 것은 응용프로그램의 몫입니다. 데이터는 받는 버퍼에 구분 없이 연결되어 들어가 있는 것입니다. 이점을 항상 염두하고 프로그래밍을 해야 합니다. 즉, 서버에서 recv 를 했을 때 받은 크기는 100 이 아닐 수 있습니다. 100보다 클 수 있고 작을 수도 있습니다. &lt;/P&gt;
&lt;P&gt;TCP 클라이언트 함수에 대해서 알아보도록 하겠습니다. &lt;/P&gt;
&lt;P&gt;먼저 TCP 클라이언트 작성 순서를 알아보면, &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;socket()함수로 소켓을 생성 
&lt;LI&gt;connect() 서버와의 연결 
&lt;LI&gt;send() recv() 사용하여 통신 
&lt;LI&gt;close()로 연결 닫음 &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;이런 식으로 작성 합니다. connect()란 함수 말고는 나머지는 서버와 비슷합니다. 클라이언트는 bind() 함수를 사용하지 않는데 그것은 포트번호를 꼭 일정하게 묶을 필요가 없기 때문입니다. 커널이 알아서 적당하고 사용하지 않는 포트번호를 할당해 줍니다. &lt;/P&gt;&lt;PRE&gt;int connect( int socket, struct sockaddr * foreignAddress,
             unsigned int addressLength );
&lt;/PRE&gt;
&lt;P&gt;첫 번째 socket는 생성한 소켓의 번호입니다. 그리고 두 번째는 쉽게 말해 서버의 주소를 넣어서 보내는 것입니다. 그렇게 하면 그 쪽으로 연결을 요청해서 there-why handshake 를 하는 것입니다. addressLength 는 sockaddr 의 크기입니다. &lt;/P&gt;
&lt;H3 id=header19&gt;소켓옵션&lt;/H3&gt;
&lt;P&gt;소켓옵션은 일반적으로 디폴트로 사용해도 문안하게 사용할 수가 있습니다. 그러나 보다 세밀한 설정을 하길 바란다면 이러한 옵션들을 설정하여 그 어플리케이션에 맞게 사용할 수 있습니다. 소켓 옵션에는 많은 것들이 있으니 Unix Network Programming vol 1 의 7장에 소켓 옵션에 대해서 잘 설명해 놓았습니다. 그것을 참고하시길 바랍니다. 여기서는 자주 쓰이는 옵션에 대해서 알아 보도록 하겠습니다. 그 전에 소켓을 옵션을 설정하고 설정된 것을 얻어 오는 함수를 알아보도록 하겠습니다. &lt;/P&gt;&lt;PRE&gt;int getsockopt( int socket, int level, int optname,
                void * optVal, unsigned int * optLen );
int setsockopt( int socket, int level, int optname,
                const void * optVal, unsigned int * optLen );
&lt;/PRE&gt;
&lt;P&gt;위의 두 개의 함수입니다. 하나는 얻어 오는 함수고 하나는 설정하는 함수입니다. 첫 번째 인자는 소켓 옵션을 얻어오거나 설정할 소켓의 번호입니다. 두 번째 인자는 소켓의 레벨인데, 어떤 것을 설정 혹은 얻을 것이냐 하는 겁니다. 일반적인 소켓의 옵션인가 IP에 관한 내용인가? TCP에 관한 내용인가? 아니면 IPv6의 내용인가? 하는 것을 나타냅니다. 여기에는 다음과 같은 것들이 있습니다. &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;SOL_SOCKET : 일반적인 소켓의 옵션들이 있습니다. 
&lt;LI&gt;IPPROTO_IP : IP설정과 관계있는 곳: 주로 멀티캐스트와 관련된 것들이 있습니다. 
&lt;LI&gt;IPPROTO_TCP : TCP와 관련있는 옵션들이 있습니다. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;세 번째 인자는 그 레벨에서 어떤 것을 말하느냐입니다. 일반적인 소켓의 옵션에서도 그 중에 무엇을 변경 혹은 얻어 올 것인가 하는 것입니다. 버퍼의 크기를 변경할 건지 아니면 브로드캐스드인지 등 그런 세부적인 옵션을 말합니다.%%% 네 번째 인자는 setsockopt 함수에서는 설정될 값이 무엇이냐 하는 것이고, getsocketopt 함수에서는 얻은 값을 저장할 변수의 포인터입니다.%%% 다섯 번째는 네 번째 변수의 길이입니다. 변수라 말했지만 이것은 구조체로 된 것도 있습니다.%%% 네 번째 인자를 보면 void * 형 입니다. 이것은 무엇을 말할까요. 즉, 변수의 형이 정해지지 않았다는 것입니다. 각 옵션에 따라 int도 있고, unsigned char도 있고, 구조체도 있습니다. &lt;/P&gt;
&lt;P&gt;이제 자주 사용하는 옵션들에 대해서 알아보도록 하겠습니다. &lt;/P&gt;
&lt;P&gt;1) SOL_SOCKET Level &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;SO_RCVBUF, SO_SNDBUF &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;버퍼의 크기를 바꾸는 옵션입니다. 커널의 recv Buffer, send Buffer의 크기를 조절하는 데 사용합니다. 이것을 어떻게 잘 설정하느냐에 따라 성능이 향상된다고 합니다. 버터의 크기는 테스트와 네트워크의 상태에 따라서 달라진다고 합니다. 그런데 보통은 (대역폭 * 지연율) * 2 의 공식에 따라 버퍼의 크기를 설정한다고 합니다. recv Buffer 의 크기를 변경하는 코드를 보도록 하겠습니다. &lt;/P&gt;&lt;PRE&gt;int rcvBufferSize;
int sockOptSize;
.
.
.
// 소켓 리시브 버퍼 크기 얻기
sockOptSize = sizeof( rcvBufferSize );
if( getsockopt( sock, SOL_SOCKET, SO_RCVBUF, &amp;amp;rcvBufferSize, &amp;amp;sockOptSize ) &amp;lt; 0 )
{
        printf( &quot;getsockopt() failed
&quot; );
        exit( 1 );
}
// 리시브 버퍼의 크기를 2배로 만든다.
rcvBufferSize *= 2;
if( setsockopt( sock, SOL_SOCKET, SO_RCVBUF, &amp;amp;rcvBufferSize, sizeof( rcvBufferSize ) &amp;lt; 0 ) )
{
        printf( &quot;setsockopt() failed
&quot; );
        exit( 1 );
}
&lt;/PRE&gt;
&lt;P&gt;여기에서 보면 SOL_SOCKET, SO_RCVBUF 가 나옵니다. 즉, 일반적인 소켓의 옵션 중에 recv Buffer 의 크기를 말합니다. recv Buffer 와 마찬가지로 send Buffer 변경 옵션은 SOL_SOCKET level에 있습니다. 그리고 SO_RCVBUF 대신에 SO_SNDBUF라는 것을 넣어 주면 변경이 가능합니다. &lt;/P&gt;
&lt;P&gt;그런데 하나 주의 하실 점이 있습니다. 바로 호출 순서입니다. 소켓의 옵션들의 대부분이 호출 순서가 중요합니다. 클라이언트의 경우 connect() 하기 전에 recv Buffer 를 변경해야 하는데, 왜냐하면 three-way handshake 할 때 MSS를 알려 주기 때문입니다. 그리고 서버의 경우에 listensocket (listen() 함수 호출 시 전달되는 소켓번호) 의 설정은 listen() 호출 전에 먼저 설정을 해주어야 합니다. 쉽게 설명해서 연결이 성립될 때 그러니까 three-way handshake할 때 한번에 보낼 수 있는 TCP 세그먼트(패킷)의 크기의 최대값을 알려 줍니다. 연결이 성립되면 최대 세그먼트의 크기(MSS)를 변경할 수 없어 연결하기 전에 미리 바꾸어 두는 것입니다. &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;SO_LINGER &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;SO_LINGER 옵션이 있습니다. 이것은 TCP 에서 적용되는 것인데 close함수의 행동을 지정하는 옵션입니다. close() 하면 recv Buffer 나 send Buffer 에 보내거나 받을 데이터가 있다면 전부 처리 후 close() 를 합니다. 그 방법을 바꾸는 것입니다. 먼저 전달되는 구조체에 대해서 알아 보도록 합시다. &lt;/P&gt;&lt;PRE&gt;struct linger
{
    int l_onoff;
    int l_linger;
};

setsockopt( sock, SOL_SOCKET, SO_LINGER, &amp;amp;linger 구조체 주소, sizeof( linger ) );
&lt;/PRE&gt;
&lt;P&gt;이런 식으로 호출하면 되겠죠. 그리고 세부적인 동작 설정은 linger구조체의 변수 설정에 있습니다. &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;l_onoff가 0이면 기본적인 TCP동작이 적용됩니다. 
&lt;LI&gt;l_onoff가 0이 아니고(주로 1을 넣습니다.) l_linger가 0이면 연결이 닫힐 때 버퍼의 내용을 버리고 연결을 끊어 버립니다. 
&lt;LI&gt;l_onoff가 0이 아니고 l_linger도 0이 아니면 소켓이 닫힐 때 블럭 당한다고 합니다. &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;이 소켓옵션을 쓸 땐 2번을 주로 씁니다. 쓰는 이유는 만약 서버가 종료되고 다시 시작 할 때 입니다. 연결이 끊어지고 남은 데이터를 전송합니다. 그때 남은 데이터를 보낸다면 클라이언트에게 ack 메시지(받았다는 확인 메시지)를 받아야 완전한 종료가 이루어집니다. 그 메시지를 기다리는 시간이 있습니다. 만약 그것을 다 받지 못했다면 다시 보내야 하지요. 그런 상황에서 다시 서버를 시작하려고 하면 이미 사용 중인 포트라는 에러를 내게 됩니다. 그래서 이런 옵션을 사용하는 것입니다. 그런데 그것은 바람직한 해결 방법이 아니라고 합니다. 그래서 이런 옵션은 추천되고 있지 않습니다. 이에 대한 해결책은 따로 있습니다. 그것이 다음에 설명할 포트 재사용 옵션입니다. &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;SO_REUSEADDR &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;이 옵션을 선택하여 주면 위의 예에서 말한 서버 재 시작 시 다시 시작할 수 있습니다. 간단히 사용법을 알아보도록 하지요. &lt;/P&gt;&lt;PRE&gt;int nResue = 1;
setsockopt( ListenSocket, SOL_SOCKET, SO_REUSEADDR, &amp;amp;nReuse, sizeof( nReuse ) );
&lt;/PRE&gt;
&lt;P&gt;이것도 호출 순서가 있는데 bind() 하기 전에 이 옵션을 설정해 놓아야 합니다. 이렇게 하면 소켓의 포트를 재 사용할 수 있습니다. &lt;/P&gt;
&lt;P&gt;2) IPPROTO_IP Level &lt;/P&gt;
&lt;P&gt;여기에는 주로 멀티캐스트와 관련된 옵션들이 있습니다. 다음에 멀티캐스트를 하실 때 그때 사용법을 참고하기면 됩니다. &lt;/P&gt;
&lt;P&gt;3) IPPROTO_TCP Level &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;TCP_NODELAY &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;TCP에 보면 잔잔한 패킷들을 하나씩 다 보내는 것이 아니라 네트워크상에 작은 패킷들을 줄이기 위해 Nagle 알고리즘을 사용하여 어느 정도 묶어서 한꺼번에 보내는 것이 있습니다. 이것을 사용 할지 안 할지를 설정하는 옵션입니다. 이것은 주로 서버에서는 이 알고리즘을 사용 안 한다고 합니다. 왜냐하면 다른 일을 해야 하기 때문에 그냥 바로 보내버리는 것이 더욱 효과적이라는 것입니다. 패킷의 개수가 많아지기는 하지만 그런 알고리즘의 딜레이를 버림으로 보다 빠른 처리를 할 수 있다는 것입니다. 그러나 클라이언트의 경우는 Nagle알고리즘을 사용합니다. 작은 패킷을 묶어 보내 네트워크의 부하를 줄이자는 것입니다. &lt;/P&gt;
&lt;P&gt;소켓 옵션은 다양하고 많은 것들이 있고 주의 사항들이 있습니다. 항상 자신의 프로그램에 맞게 올바른 설정을 하시고 사용하시기 전에 여러 가지로 알아보시고 하시기를 바랍니다. 그리고 옵션에서 인자 값을 넘길 때 인자의 형이 다릅니다. 위의 예제에서도 Linger옵션은 구조체를 사용하고 다른 것은 int 형이었습니다. 그리고 윈속(Winsock)도 다릅니다. 구조체로 된 부분은 거의 같지만 int로 된 부분은 BOOL로 사용하는 부분이 많이 있습니다. 잘 알아 보시고 사용하시기 바랍니다. &lt;/P&gt;
&lt;H3 id=header20&gt;에코 프로그램&lt;/H3&gt;
&lt;P&gt;그럼 이제 소스를 보면서 이제까지의 내용들을 정리하도록 하겠습니다. 여기의 모든 소스는 유닉스나 리눅스 용입니다. 윈도우에서는 실행이 되지 않습니다. &lt;/P&gt;
&lt;P&gt;구현할 것은 에코 서버와 클라이언트입니다. 에코 서버는 에코 클라이언트가 보낸 데이터를 받아서 그대로 다시 에코 클라이언트에게 보내는 것입니다. 그럼 에코 서버부터 보도록 하겠습니다. &lt;/P&gt;
&lt;H4 id=header21&gt;에코 서버&lt;/H4&gt;
&lt;P&gt;서버의 실행은 &amp;lt;실행파일명 포트번호&amp;gt; 입니다. &lt;/P&gt;&lt;PRE&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt; // socket() bind() connect()
#include &amp;lt;arpa/inet.h&amp;gt;  // socketaddr_in,  inet_ntoa()
#include &amp;lt;netinet/in.h&amp;gt; // 만약 FreeBSD 라면 이 해더를 추가해야 한다.
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

#define RCVBUFSIZE 128
#define MAXPENDING 5

int main( int argc, char * argv[] )
{
        struct sockaddr_in echoServAddr, echoClntAddr;
        int servSock, clntSock;
        unsigned short echoServPort;
        unsigned int clntLen;
        char echoBuffer[BUF_LEN];
        int recvMsgSize;

        if( argc != 2 )
        {
                printf( &quot;Usage : %s port
&quot;, argv[0] );
                exit( 1 );
        }

        echoServPort = atoi( argv[1] );

        if( ( servSock = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP ) ) &amp;lt; 0 )
        {
                printf( &quot;socket() failed
&quot; );
                exit( 1 );
        }

        memset( &amp;amp;echoServAddr, 0, sizeof( echoServAddr ) );
        echoServAddr.sin_family = AF_INET;
        echoServAddr.sin_addr.s_addr = htonl( INADDR_ANY );
        echoServAddr.sin_port = htons( echoServPort );

        if(bind(servSock, (struct sockaddr *) &amp;amp;echoServAddr, sizeof(echoServAddr)) &amp;lt; 0)
        {
                printf(&quot;bind() failed
&quot;);
                exit(1);
        }

        if(listen(servSock, MAXPENDING) &amp;lt; 0)
        {
                printf(&quot;listen() failed
&quot;);
                exit(1);
        }

        for(;;)
        {
                clntLen = sizeof(echoClntAddr);

                if((clntSock = accept(servSock, (struct sockaddr *)
                    &amp;amp;echoClntAddr, &amp;amp;clntLen)) &amp;lt; 0)
                {
                        printf(&quot;accept() failed&quot;);
                        exit(1);
                }

                if((recvMsgSize = recv(clntSocket, echoBuffer, RCVBUFSIZE, 0))
                   &amp;lt; 0)
                {
                        printf(&quot;recv() failed&quot;);
                        exit(1);
                }
                while(recvMsgSize &amp;gt; 0)
                {
                        if(send(clntSocket, echoBuffer, recvMsgSize, 0)
                            != recvMsgSize)
                        {
                                printf(&quot;send() failed&quot;);
                                exit(1);
                        }
                        if((recvMsgSize = recv(clntSocket, echoBuffer,
                            RECVBUFSIZE, 0)) &amp;lt; 0)
                        {
                                printf(&quot;recv() failed&quot;);
                                exit(1);
                        }
                }
                close(clntSocket);
        }
}
&lt;/PRE&gt;
&lt;P&gt;자, 이게 에코서버의 모습입니다. 우선 소스부터 분석하도록 합시다. 우선 서버의 소켓을 열고 서버의 주소 정보를 채우고 bind 시키고 클라이언트의 요구를 듣는 상태로 들어 갔습니다. 그리고 클라이언트의 연결요청이 들어오면 accept함수를 호출하여 클라이언트와 연결을 하고 그리고 에코 서비스를 해주는 과정으로 되어있습니다. 지금 제가 설명한 과정이 분석이 되실 겁니다. 그래도 좀더 자세히 설명에 들어가도록 합시다. 이 서버는 TCP 서버입니다. 그것을 알 수 있는 부분은 어디입니까? 소켓을 처음 생성하는 부분입니다. &lt;/P&gt;&lt;PRE&gt;servSock = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
&lt;/PRE&gt;
&lt;P&gt;여기서 SOCK_STREAM 으로 되어있습니다. 이것은 연결형 서버를 말하는 겁니다. 즉, TCP의 서비스를 이용하겠다는 것입니다. 여기서 마지막 인자를 IPPROTO_TCP 라고 되어있는데 꼭 이렇게 써주는 것은 아닙니다. 보통은 0 값을 전달합니다. 어느 것을 사용하나 상관은 없습니다. 명시적인 것이 좋으신 분은 IPPROTO_TCP라고 써주시면 되겠습니다. 여기서 PF_INET 를 사용했는데 AF_INET 와 무엇이 다를까요? PF 는 Protocol Family 의 약자이고 AF는 Address Family의 약자입니다. 글자는 달라고 내부적으로는 구분하지 않는다고 합니다. 그래서 여러 곳에서는 각각 다릅니다. PF_INET를 사용하는 것이 있고 AF_INET를 사용하는 곳도 있습니다. 여기에 접두어가 자신이 알기 쉽다고 생각하시는 것을 사용하시면 될 듯합니다. 중요한 것은 IPv4라는 겁니다. IPv6은 AF_INET6이라는 것을 사용합니다. 만약에 IP프로토콜 독립적으로 구성하고자 하시려면 이것을 고려 해주셔야 합니다. 다음으로 서버의 주소를 지정하고 bind 시켰습니다. &lt;/P&gt;&lt;PRE&gt;memset( &amp;amp;echoServAddr, 0, sizeof( echoServAddr ) );
echoServAddr.sin_family = AF_INET;
echoServAddr.sin_addr.s_addr = htonl( INADDR_ANY );
echoServAddr.sin_port = htons( echoServPort );

if( bind( servSock, ( struct sockaddr * ) &amp;amp;echoServAddr, sizeof( echoServAddr ) ) &amp;lt; 0 )
{
        printf( &quot;bind() failed
&quot; );
        exit( 1 );
}
&lt;/PRE&gt;
&lt;P&gt;이 부분입니다. 여기서 3번째 줄에 INADDR_ANY 라는 단어가 들어 갑니다. 서버의 IP 주소를 넣어 주는 부분입니다. 직접 IP 주소를 넣어 주어도 상관은 없습니다. 그런데 이렇게 하면 만약에 서버의 IP가 바뀌거나, 다른 곳에서 서버를 가동시켜야 한다면, 이 부분도 바꾸어야 합니다. 그러면 위 소스에서 쓰는 것처럼 쓰는 것이 더욱 좋을 것입니다. 그런데 중요한 것은 그것이 아닙니다. 서버는 (꼭 서버만 아니고) IP가 여러 개인 서버도 있습니다. 그럴 경우 예를 들면, 여기서 bind 한 포트를 5000번이라고 합시다. 그리고 서버의 IP가 203.241.228.57 과 203.241.228.66 두 개의 IP를 가지고 있다고 하면, 클라이언트가 서버의 아무 IP를 가지고 포트 5000으로 들어오면 우리의 서버 어플리케이션에서 받겠다는 것입니다. 즉, IP : 203.241.228.57, Port 5000 ... IP : 203.241.140.66, Port 5000 으로 접속하는 모든 클라이언트의 요청을 받겠다는 것입니다. 내부적으로는 INADDR_ANY는 0의 값이 들어가 있다고 합니다. 위 서버 코드에서 서버의 IP를 출력해 보세요. 그럼 0.0.0.0 이 출력 될 겁니다. &lt;/P&gt;
&lt;P&gt;간단히 실험하나 해보도록 하겠습니다. 도스 명령프롬프트 창을 열어서 &lt;/P&gt;&lt;PRE&gt; &amp;gt;nslookup daum.net

&lt;/PRE&gt;
&lt;P&gt;라고 쳐봅니다. 물론 네트워크가 되는 컴퓨터에서요. daum의 IP주소가 나오는데 여러 개가 나옵니다. 위 명령은 네임서버에 daum의 정보를 얻어 오는 것입니다. &lt;/P&gt;
&lt;P&gt;서버에서 에코 서비스를 처리하는 부분을 보도록 하겠습니다. &lt;/P&gt;&lt;PRE&gt;for(;;)
{
        clntLen = sizeof(echoClntAddr);

        if((clntSock = accept(servSock,
             (struct sockaddr *) &amp;amp;echoClntAddr, &amp;amp;clntLen)) &amp;lt; 0)
        {
                printf(&quot;accept() failed&quot;);
                exit(1);
        }

        if((recvMsgSize = recv(clntSocket, echoBuffer, RCVBUFSIZE, 0)) &amp;lt; 0)
        {
                printf(&quot;recv() failed&quot;);
                exit(1);
        }

        while(recvMsgSize &amp;gt; 0)
        {
                if(send(clntSocket, echoBuffer, recvMsgSize, 0)
                      != recvMsgSize)
                {
                        printf(&quot;send() failed&quot;);
                        exit(1);
                }
                if((recvMsgSize = recv(clntSocket, echoBuffer,
                      RECVBUFSIZE, 0)) &amp;lt; 0)
                {
                        printf(&quot;recv() failed&quot;);
                        exit(1);
                }
        }
        close(clntSocket);
}
&lt;/PRE&gt;
&lt;P&gt;이 부분입니다. 클라이언트가 보낸 문자를 되돌려 보내는 부분입니다. 일단 무한 루프로 서버는 끝나지 않습니다. 여기에서 보면, 처음에 recv를 받고 send를 하고 다시 recv를 받습니다. 클라이언트는 처음 에코 요구를 하면 문자열을 한번만 보내는데 여기서는 한번 받고 루프를 돌면서 보내고 받고 그럽니다. 왜냐면 네트워크의 상태에 따라서 TCP는 얼마나 받을지 모른다는 것입니다. 그래서 루프를 돌면서 못 받은 데이터가 있으면 받아서 보내 줍니다. &lt;/P&gt;
&lt;P&gt;여기서 에코 서버와 에코 클라이언트의 시나리오를 생각해 보도록 합시다. 서버가 일단 가동되고 있고, 그리고 클라이언트가 Hello라는 문자를 보내 서버에게 에코 요구를 보냅니다. 그런데 네트워크 상황이 안 좋아서 서버는 Hell 까지만 받고 말았습니다. 이것은 첫 번째의 recv 에서 받은 데이터입니다. 그러고 while로 들어가 send에서 서버는 Hell을 클라이언트에게 보냅니다. 그리고 다시 recv 로 들어갑니다. 그리고 o 라는 문자가 옵니다. 그리고 서버는 recv 로 받아서 다시 클라이언트에게 o를 보내어 줍니다. 그리고 다시 recv로 들어 갑니다. 그러면 여기서 서버는 recv 에서 블럭 됩니다. 네트워크에 어떤 데이터가 들어올 때까지 블록 되는 것입니다. 그럼 언제 recv가 리턴 되는가 하면 TCP는 연결을 끝내고 close를 할 때 recv에 0을 리턴 합니다. 설정될 때 three-way handshake하는 것처럼 연결을 끊을 때도 이와 비슷한 행동을 합니다. 그러니까 명시적으로 끊겠다고 하는 것이죠. 서버가 먼저 끊을 수 있고 클라이언트가 먼저 끊을 수도 있습니다. 어느 한쪽에서 close를 하면 “끊겠다”는 패킷을 다른 쪽에 보내면 다른 한쪽에서는 “알았다는 그리고 끊겠다”는 그런 종류의 단계를 취하는 것입니다. 그러면 여기서는 클라이언트가 먼저 끊었다고 합시다. 그럼 서버의 블록 된 recv는 0을 리턴 합니다. 그리고 while 루프를 끝냅니다. 그리고 마지막에 서버가 close를 해서 클라이언트와 연결을 닫습니다. &lt;/P&gt;
&lt;P&gt;이제 서버의 구조에 대해 알아 봅시다. 위 서버는 클라이언트당 하나의 소켓이 열립니다. 처음 서버에서 소켓을 열어 listen() 함수에 전달하는 소켓을 보통 듣는 소켓(listen socket)이라고 합니다. 연결 요청은 이 소켓으로 들어 옵니다. 연결요청이 들어 오면 accept()로 다시 소켓 하나를 열어서 새로이 열린 소켓으로 클라이언트와 통신을 하는 것입니다. 그럼 이제 이 서버의 문제점을 알아 봅시다. recv에서 데이터를 받으면 블록 된다고 했습니다. 그런 클라이언트가 접속을 끝내지 않는다면, 다른 클라이언트의 서비스는 어려움이 많이 있습니다. 그리고 서버가 여러 가지 복잡한 일을 하는 것이라면, recv가 블록 되 프로세스가 놀고 있게 되어 효율적이지 못합니다. 그래서 이 문제를 해결하기 위해 넌 블로킹 모드, 비동기 모드 등이 나옵니다. 기본적인 서버의 구조와 네트워크는 데이터를 주고 받을 때 무엇이든 확신할 수 없다는 것. 지금 받은 것이 다 받은 것인지 보낸 것이 전부 보내어졌는지를 어떻게 확인하고 처리하는지 이해하시기를 바랍니다. &lt;/P&gt;
&lt;P&gt;그럼 이번에는 클라이언트를 보기로 하지요. 클라이언트는 서버보다 간단하니 한번 보시면서 분석해 보시기 바랍니다. 보낸 데이터를 에코 해서 받을 때 어떻게 받았는지 어떻게 다 받았는지 클라이언트는 자신이 서버에 보낸 문자의 길이를 알고 있기 때문에 이것을 활용했습니다. 한번 보시면 이해하시리라 생각합니다. &lt;/P&gt;
&lt;H4 id=header22&gt;에코 클라이언트&lt;/H4&gt;
&lt;P&gt;그럼 이제 클라이언트 소스입니다. &lt;/P&gt;
&lt;P&gt;클라이언트의 실행은 &amp;lt;실행파일명 서버IP 에코문자 포트&amp;gt; 입니다. &lt;/P&gt;&lt;PRE&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt; // socket() bind() connect()
#include &amp;lt;arpa/inet.h&amp;gt;  // socketaddr_in,  inet_ntoa()
#include &amp;lt;netinet/in.h&amp;gt; // 만약 FreeBSD 라면 이 해더를 추가해야한다.
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

#define RCVBUFSIZE 128

int main(int argc, char * argv[])
{
        int sock;
        struct sockaddr_in echoServAddr;
        unsigned short echoServPort;
        char * servIP;
        char * echoString;
        char echoBuffer[RCVBUFSIZE];
        unsigned int echoStringLen;
        int bytesRcvd, totalBytesRcvd;

        if((argc &amp;lt; 3) || (argc  &amp;gt; 4))
        {
                printf(&quot;Usage: %s &amp;lt;Server IP&amp;gt; &amp;lt;Echo Word&amp;gt; [&amp;lt;Echo Port&amp;gt;]
&quot;, argv[0]);
                exit(1);
        }

        servIP = argv[1];
        echoString = argv[2];

        if(argc == 4)
                echoServPort = atoi(argv[3]);
        else
                echoServPort = 7; // 에코 서버의 well-know port입니다..

        if((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) &amp;lt; 0)
        {
                printf(&quot;socket() failed&quot;);
                exit(1);
        }

        memset(&amp;amp;echoServAddr, 0, sizeof(echoServAddr));
        echoServAddr.sin_family = AF_INET;
        echoServAddr.sin_addr.s_addr = inet_addr(servIP);
        echoServAddr.sin_port = htons(echoServPort);

        if(connect(sock, (struct sockaddr *) &amp;amp;echoServAddr, sizeof(echoServAddr)) &amp;lt; 0)
        {
                printf(&quot;connect() failed&quot;);
                exit(1);
        }

        echoStringLen = strlen(echoString);

        if(send(sock, echoString, echoStringLen, 0) != echoStringLen)
        {
                printf(&quot;send() failed&quot;);
                exit(1);
        }

        totalBytesRcvd = 0;
        printf(&quot;Received: &quot;);

        while(totalBytesRcvd &amp;lt; echoStringLen)
        {
                // 문자끝 NULL을 넣기 위해 RCVBUFSIZE-1
                if((bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE-1,
								0)) &amp;lt;= 0)
                {
                        // 리턴값이 0이면 서버와 연결이 끊어짐..
                        printf(&quot;recv() 실패 혹은 서버와 연결이 끊어졌다.&quot;);
                        exit(1);
                }

                totalBytesRcvd += bytesRcvd;
                echoBuffer[bytesRcvd] = &apos;&apos;;
                printf(echoBuffer);
        }
        printf(&quot;
&quot;);

        close(sock);
        exit(0);
}
&lt;/PRE&gt;
&lt;H2 id=header23&gt;I/O 모델&lt;/H2&gt;
&lt;P&gt;&lt;SPAN class=wikiunknown&gt;&lt;A class=con_link href=&quot;http://www.gpgstudy.com/gpgiki/Unix%20Network%20Programming?action=edit&quot; target=_blank&gt;&lt;FONT style=&quot;BACKGROUND-COLOR: #660000&quot; color=#ffffff&gt;?&lt;/FONT&gt;&lt;/A&gt;&lt;FONT color=#660000&gt;Unix Network Programming&lt;/FONT&gt;&lt;/SPAN&gt; 6장에 보면 I/O 모델에 대한 이야기가 나옵니다. 우선 그 모델을 살펴 보도록 하겠습니다. &lt;/P&gt;
&lt;H3 id=header24&gt;Blocking I/O&lt;/H3&gt;
&lt;P&gt;위의 에코서버가 Blocking mode 입니다. 소켓을 열면 기본적으로 Blocking mode가 되는 것이지요. 말 그대로 Blocking 당한다고 생각하시면 되겠습니다. 위의 에코 서버를 생각해 봅시다. 에코 서버는 클라이언트로부터 데이터를 받기 위해 recv() 함수를 호출합니다. 그리고 프로세스는 클라이언트로 데이터가 올 때까지 멈춰있습니다. 그것이 Blocking 입니다. 그 함수가 일을 마칠 때까지 기다리고 있는 것입니다.%%% 에코 서버처럼 간단하고 해야 할 일이 별로 없는 서버는 Blocking으로 만드는 것이 가능합니다. 그러나 게임같이 서버에서 많은 일을 하는 그리고 많은 사용자들을 처리하는 서버에는 알맞지 않습니다. 왜냐하면 한 클라이언트에게 데이터를 받기 위해 recv()에서 서버가 멈춰있다면 다른 클라이언트에게 피해가 있고, 다른 필요한 처리를 하는데 서버가 놀고 있게 되기 때문입니다. 그럼 그런 부분에서 함수를 바로 리턴하게 한다면 즉, 만약 리시브를 호출해서 받을 데이터가 있으면 받고 없다면 넘어가서 다른 일을 하면 될 것입니다. &lt;/P&gt;
&lt;H3 id=header25&gt;Non-Blocking I/O&lt;/H3&gt;
&lt;P&gt;이렇게 나온 것이 Non-blocking 입니다. Non-blocking 은 요청한 I/O를 그 상황에서 할 수 있으면 하고 할 수 없다면 거기서 멈추지 말고 함수를 리턴하여 다른 작업을 할 수 있게 해주는 것입니다.%%% 여기서 리턴될 때(I/O를 할 수 없어 리턴될 때) 다른 오류 코드를 리턴 한다면 I/O가 이루어졌는지 안 이루어 졌는지를 알 수 있을 것입니다. 그렇게 동작하는 모드가 Non-Blocking입니다.%%% 그런데 여기서는 몇 가지 문제가 있는데 만약에 요청한 I/O를 할 수 없다면 클라이언트로부터 데이터는 받아야 하니 데이터를 받을 때까지 확인하는 작업이 필요해 지는 것입니다. 계속 반복문을 돌려 데이터를 다 받았는지를 확인 해야 하는 것입니다. 그것을 Polling 이라고 부릅니다. 이것은 CPU의 시간낭비인데 그것을 줄이는 방법은 어떤 것이 있을까요. 서버가 여러 가지 일을 하고 있는 상황에서 클라이언트가 어떤 데이터를 보내왔다고 하면, 그럼 여기서 누군가가 클라이언트가 데이터를 보내왔다는 것을 서버에게 알려 준다면, 그러면 폴링(polling)을 하는 것보다는 조금 더 좋은 성능을 보여 줄 수 있을 것입니다. &lt;/P&gt;
&lt;H3 id=header26&gt;I/O Multiplexing&lt;/H3&gt;
&lt;P&gt;번역하자면 입출력 다중화라고 합니다. selcet()함수나 poll()함수를 이용하여 실제적으로 구현합니다. 이런 함수들을 이용하여 I/O를 호출하면 실제적으로는 시스템에서 blocking 됩니다. 어플리케이션에서는 blocking 당해 있지는 않습니다. 여기에 여러 개의 소켓들을 설정하여 그 소켓에 send, recv, error 등을 설정할 수 있습니다. 그러면 시스템에서 그런 설정된 사항에 맞는 상황이 일어나면 어플리케이션에게 그 사항을 알려줍니다. 그러면 어플리케이션에서 그것을 보고 알맞은 처리를 해주는 것이죠. 그러나 여기에도 단점이 있는데 한번에 select로 설정해 줄 수 있는 소켓의 개수가 제한이 다?것입니다. &lt;/P&gt;
&lt;H3 id=header27&gt;Signal Driven I/O&lt;/H3&gt;
&lt;P&gt;이 방법은 인터럽트와 비슷하다고 생각하시면 됩니다. 이것은 만약에 어떤 I/O를 요청하고 그것이 준비가 되면 어플리케이션에게 신호를 보내어 준비되었다는 것을 알려 주는 것이지요. 만약에 이러한 방법을 쓴다고 한다면 클라이언트에게서 데이터가 들어 왔다면 어플리케이션에서 지정한 신호가 어플리케이션으로 온다는 겁니다. 어플리케이션에서는 그러한 신호를 받으면 그에 따른 적당한 처리를 해주면 됩니다. 그런데 여기에도 약간의 문제가 있습니다. 그 신호라는 것이 중복되어 들어 온다면 뒤에 온 신호는 무시됩니다. 그리고 이 방법은 TCP 에는 적당하지 않다고 하는데 왜냐하면 TCP 에서는 신호를 설정해두면 수많은 신호들이 어플리케이션에게 온다고 합니다. 그리고 신호가 발생되어도 어떤 일이 있었는지 알 수 없다고 합니다. 그래서 주로 UDP에서 사용한다고 합니다. &lt;/P&gt;
&lt;H3 id=header28&gt;Asynchronaus I/O&lt;/H3&gt;
&lt;P&gt;Signal Driven I/O 에서는 I/O작업이 시작되는 순간에 신호를 보내어 알려 주는 것입니다. 비동기에서는 I/O작업이 완료되었을 때 이 사실을 알려주는 방식입니다. &lt;/P&gt;
&lt;P&gt;대략적으로 개념은 이해하시리라 생각이 듭니다. 많은 방법들이 있습니다. Blocking 에서는 block 당하는 것을 해결하려고 non-blocking 이 나오고 non-blocking 의 폴링(polling)을 해결하려는 여러 가지 방법들이 나온 것 같습니다. &lt;/P&gt;
&lt;P&gt;유닉스에서는 주로 I/O Multiplexing 을 많이 사용한다고 합니다. 그러나 실제 성능을 테스트해보면 non-blocking 이 가장 좋은 성능을 낸다고 합니다. 그런데 non-blocking 은 적성이 힘들고, 유지보수가 힘들다고 합니다. 그래서 I/O Multiplexing 을 사용하라고 권장하는 것 같습니다. &lt;/P&gt;
&lt;P&gt;요즘에는 kqueue 가 BSD 계열 유닉스에서는 그것이 가장 좋은 성능을 낸다고 하고 윈도우에는 IOCP(I/O complete port)가 좋은 성능을 낸다고 합니다. 그러면 이런 좋은 성능을 내는 것만 사용하면 되지 않을까요? 그런 건 아닌 것 같습니다. 그 서버의 역할에 맞는 I/O 모델을 사용하는 것이 가장 효율적일 것입니다. Blocking 으로 충분히 감당할 수 있는 서버인데 무리해서 다른 모델을 도입하는 것은 개발 속도와 유지보수 면에서 불리한 면이 있을 수 있습니다. 그리고 서버의 여러 가지 설계, 그런 부분에서 해당 서버에 잘 맞는 I/O 모델을 선택해서 쓰면 되겠지요. &lt;/P&gt;
&lt;H3 id=header29&gt;I/O Multiplexing 예제&lt;/H3&gt;
&lt;P&gt;이제 위의 에코 서버를 다시 작성해 봅시다. &lt;/P&gt;
&lt;P&gt;위의 에코 서버는 한번에 한 사용자만을 처리할 수 있는 그런 서버였습니다. 그런데 서버에서 한 클라이언트가 아닌 여러 클라이언트를 처리 해주는 경우가 대부분입니다. 그럼 어떤 방법으로 여러 클라이언트를 처리 할까요? 일단 blocking으로 생각을 해보면 앞 강좌와 같은 코드가 나올 겁니다. (따로 스레드나 프로세스를 생성하지 않는다면 말이지요.) 이 방법은 한 클라이언트가 접속을 끝내지 않는다면 다른 사용자들은 끝날 때까지 가만히 기다리고 있는 그런 상황에 이르게 됩니다. &lt;/P&gt;
&lt;P&gt;그럼 위에서 나온 다른 방법을 한번 살펴 보죠. 우리는 TCP이기 때문에 시그널방식은 접어두고, non-blocking 은 폴링(polling)을 사용해야 하고 성능은 좋지만 간단한 에코 서버이기 때문에 굳이 복잡하게 프로그래밍을 할 필요가 없을 것 같습니다. 비동기 모드는 조금 더 많은 공부를 해야 하니 I/O Multiplexing 으로 하겠습니다. I/O Multiplexing 방법 중 하나가 select()를 이용하는 방법입니다. 먼저 select() 함수에 대해 알아보도록 하겠습니다. &lt;/P&gt;&lt;PRE&gt;int select( int maxDescPlus1,
            fd_set * readDescs, fd_set * writeDescs,
            fd_set * exceptionDescs,
            struct timeval * timeout );
&lt;/PRE&gt;
&lt;P&gt;이것이 select함수의 원형입니다. 인자를 반대로 가며 설명을 하겠습니다. 먼저 timeval 입니다. 이 구조체는 몇 초인지, 그리고 몇 마이크로 초인지를 설정할 수 있습니다. 구조체를 살펴보면, &lt;/P&gt;&lt;PRE&gt;struct timeval
{
    long tv_sec;  // 초
    long tv_usec; // 마이크로초
};
&lt;/PRE&gt;
&lt;P&gt;이 구조체의 필드를 채워서 보내면 어떤 입출력이 준비가 되거나 시간이 지나면 select()함수가 리턴 됩니다. 그러니까 지정된 시간 이상은 입출력의 준비를 받지 않겠다는 것입니다. 만약 이 필드에 전부 0으로 설정을 하면 지정된 입출력들을 점검한 뒤 바로 리턴 됩니다. 그리고 여기에 null값을 주면 무한히 기다리게 되는 것입니다.%%% 그 다음 인자를 보면 새로운 fd_set라는 것이 보입니다. 여기에 fd_set이라는 것으로 설정하여 시스템에게 어플리케이션에서 무엇을 해주길 바라는 지 알려 주는 것입니다. 변수 명을 보면 read, write, exception이라는 접두어가 있습니다. 말 그대로 recv에 필요한 것이면 설정하여 두 번째 인자에 넣어 주고 send가 필요하면 그 다음, exception 에 대한 처리가 필요하다면 그 다음의 인자에 설정하여 넣어 주면 되는 것입니다. 그러면 fd_set는 어떻게 생겨 먹었을까요. 여러 개의 나열된 비트 필드로 이루어져 있습니다. &lt;/P&gt;&lt;PRE&gt;소켓번호   0   1   2   3   4   5   6 ....
        -------------------------------------
        | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
        -------------------------------------
&lt;/PRE&gt;
&lt;P&gt;&amp;lt;그림&amp;gt; fd_set의 구조 &lt;/P&gt;
&lt;P&gt;만약 이렇게 하면 소켓번호 0번과 3번에 어떤 I/O가 일어 나면 알려 달라는 것입니다. 이것을 readDescs 인자에 넣으면 0번과 3번에 어떤 데이터가 들어오면 select문이 리턴 되는 것입니다. 똑같이 write와 exception인자도 동작이 똑같습니다. 그런데 0번은 표준 입력을 말합니다. 즉, 키보드를 말하지요. 1번은 표준출력을 2번은 표준에러를 말합니다. 표준에러와 출력은 주로 모니터를 가리킵니다. 소켓번호는 유닉스의 파일 디스크립터와 같다고 하였습니다. 유닉스는 전부 파일로 관리되니 0, 1, 2 는 표준 입력 출력 에러로 지정되어 있는 것입니다. 다시 위의 그림을 이야기 하면 키보드(표준입력)이나 소켓 번호 3번에 어떤 데이터가 들어오면 select가 리턴 되는 것입니다. 그런데 비트필드로 되어 있으니까 사용하기 불편합니다. 여기에는 매크로가 있습니다. 그 매크로를 이용해서 설정하고, 지우고, 확인합니다. 그 매크로를 알아보면, &lt;/P&gt;&lt;PRE&gt;매크로 명                                |설명
FD_ZERO(fd_set *fdset)         |*fdset의 모든 비트를 0으로 설정
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에 해당하는 비트가 1이고, 소켓에 I/O 변화가 생겼으면 true를 리턴
&lt;/PRE&gt;
&lt;P&gt;이렇게 있습니다. 처음에 FD_ZERO를 이용하여 초기화하고 확인할 소켓번호에 FD_SET로 설정한 뒤, select()를 호출합니다. 그리고 select가 리턴 되면, FD_ISSET로 어느 것이 입력 혹은 출력, 에러가 되었는지 확인하여 알아 내는 것입니다. 초기화는 중요합니다. 잘못된 값이 들어가는 것을 방지 하니깐요. 꼭 초기화를 해주시기 바랍니다.%%% 첫 번째 인자는 설정될 소켓번호의 최대값에 +1을 한 것입니다. +1을 한 이유는 배열과 비슷합니다. 위의 그림을 보면 0부터 시작합니다. 즉, 지정한 소켓의 최대값이 아니라 지정한 소켓의 개수를 나타내는 것이기 때문입니다.%%% select()함수의 리턴 값은 -1이면 에러를 나타내고 0이면 타임아웃을 나타냅니다. 그리고 양수이면 준비된 소켓번호의 카운터를 말합니다. &lt;/P&gt;
&lt;P&gt;그럼 소스를 보도록 하겠습니다. &lt;/P&gt;&lt;PRE&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;
#include &amp;lt;sys/time.h&amp;gt;

#define MAXPENDING 5
#define RCVBUFSIZE 512

int CreateTCPServerSocket(unsigned short port);
int AcceptTCPConnection(int servSock);
void HandleTCPClient (int clntSocket);

int main(int argc, char * argv[])
{
        int * servSock;
        int maxDescriptor;
        fd_set sockSet;
        long timeout;
        struct timeval selTimeout;
        int running = 1;
        int nPorts;
        int port;
        unsigned short portNo;

        if(argc &amp;lt; 3)
        {
                printf(&quot;Usage : %s &amp;lt;Timeout (secs.)&amp;gt; &amp;lt;Port 1&amp;gt; ...
&quot;, argv[0]);
                exit(1);
        }

        timeout = atol(argv[1]);
        noPorts = argc - 2;

        servSock = (int *) malloc(noPorts * sizeof(int));
        maxDescriptor = -1;

        for(port = 0; port &amp;lt; noPorts; port++)
        {
                portNo = atoi(argv[port + 2]);
                servSock[port] = CreateTCPServerSocket(portNo);
                if(servSock[port] &amp;gt; maxDescriptor)
                        maxDescriptor = servSock[port];
        }

        printf(&quot;Starting server : Hit return to shutdown
&quot;);
        while(running)
        {
                FD_ZERO(&amp;amp;sockSet);
                FD_SET(STDIN_FILENO, &amp;amp;sockSet);
                for(port = 0; port &amp;lt; npPorts; port++)
                        FD_SET(servSock[port], &amp;amp;sockSet);

                selTimeout.tv_sec = timeout;
                selTimeout.tv_usec = 0;

                if(select(maxDescriptor+1, &amp;amp;sockSet, NULL, NULL,
                      &amp;amp;selTimeout) == 0)
                        printf(
                        &quot;No echo requests for %ld secs... Server still alive
&quot;,
                         timeout);
                else
                {
                        if(FD_ISSET(STDIN_FILENO, &amp;amp;sockSet))
                        {
                                printf(&quot;Shutting down server
&quot;);
                                getchar();
                                running = 0;
                        }
                        for(port = 0; port &amp;lt; noPorts; port++)
                        {
                                if(FD_ISSET(servSock[port], &amp;amp;sockSet))
                                {
                                        printf(&quot;Request on port %d : &quot;, port);
                                        HandleTCPClient(
                                         AcceptTCPConnection(servSock[port]));
                                }
                        }
                }
        }

        for(port = 0; port &amp;lt; noPorts; port++)
                close(servSock[port]);
        free(servSock);
        exit(0);
}

int CreateTCPServerSocket(unsigned short port)
{
        int sock;
        struct sockaddr_in echoServAddr;

        if((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) &amp;lt; 0)
        {
                printf(&quot;socket() failed
&quot;);
                exit(1);
        }

        memset(&amp;amp;echoServAddr, 0, sizeof(echoServAddr));
        echoServAddr.sin_family = AF_INET;
        echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY);
        echoServAddr.sin_port = htons(port);

        if(bind(sock, (struct sockaddr *) &amp;amp;echoServAddr,
            sizeof(echoServAddr)) &amp;lt; 0)
        {
                printf(&quot;bind() failed
&quot;);
                exit(1);
        }
        if(listen(sock, MAXPENDING) &amp;lt; 0)
        {
                printf(&quot;listen() failed
&quot;);
                exit(1);
        }

        return sock;
}

void HandleTCPClient (int clntSocket)
{
        char echoBuffer[RCVBUFSIZE];
        int recvMsgSize;

        if((recvMsgSize = recv(clntSocket, echoBuffer, RCVBUFSIZE, 0)) &amp;lt; 0)
        {
                printf(&quot;recv() failed
&quot;);
                exit(1);
        }

        while(recvMsgSize &amp;gt; 0)
        {
                if(send(clntSocket, echoBuffer, recvMsgSize, 0) != recvMsgSize)
                {
                        printf(&quot;send() failed
&quot;);
                        exit(1);
                }
                if((recvMsgSize = recv(clntSocket, echoBuffer,
                   RCVBUFSIZE, 0)) &amp;lt; 0)
                {
                        printf(&quot;recv() failed
&quot;);
                        exit(1);
                }
        }
        close(clntSocket);
}

int AcceptTCPConnection(int servSock)
{
        int clntSock;
        struct sockaddr_in echoClntAddr;
        unsigned int clntLen;

        clntLen = sizeof(echoClntAddr);

        if((clntSock = accept(servSock,
             (struct sockaddr *) &amp;amp;echoClntAddr, &amp;amp;clntLen)) &amp;lt; 0)
        {
                printf(&quot;accept() failed
&quot;);
                exit(1);
        }
        printf(&quot;Handling client %s
&quot;, inet_ntoa(echoClntAddr.sin_addr));
        return clntSock;
}
&lt;/PRE&gt;
&lt;P&gt;전체적인 프로그램의 흐름을 보면, 사용자가 사용하겠다는 포트를 여러 개 열어서 각각 클라이언트의 요청이 들어오기를 기다리고 있습니다. 사용자가 정한 시간에 맞추어서 말이죠. 그리고 요청이 들어오면 에코 서비스를 하고 만약 사용자가 리턴 키를 누르면 서버가 종료되는 것입니다. (STDIN_FILENO가 리턴 키를 누르면 준비 됨) &lt;/P&gt;
&lt;P&gt;그러나 이 예제도 부족합니다. 여기에서는 한 클라이언트를 받던걸 여러 사용자에게 받게 하였을 뿐입니다. 한 사용자를 전부 처리 할 때까지 다시 다른 클라이언트는 기다려야 하는 것은 아직 해결되지 못했습니다.%%% 그럼 어떻게 하면 공평하게 여러 사용자를 처리 할 수 있을까요? 만약 각 클라이언트마다 그 클라이언트를 전담하는 무언가를 만든다면, 어느 정도 공평하게 클라이언트를 처리할 수 있을 겁니다.%%% 그 방법에는 클라이언트당 하나씩 프로세스를 따로 만들 수도 있습니다. 그러나 프로세스를 하나 만든다는 것은 많은 비용이 들어 갑니다. 한마디로 메모리도 많이 먹고 새로운 프로세스를 만드는 데도 시간이 많이 걸린다는 것입니다. 또한 컨텍스트 스위칭(다른 프로세스로 CPU 타임을 넘기는 행동) 하는 그 비용도 많이 듭니다. 그리고 사용자가 아주 많다면 분명 서버에 무리가 갈 것입니다.%%% 프로세스보다 비용이 조금 드는 스레드를 한번 생각해봅시다. 분명 프로세스보다 비용이 덜 드니 프로세스보다는 성능이 좋을 것입니다. 그러나 사용자가 많아진다면, 이것 또한 해결책은 아닌 것 같습니다. 그러나 서버의 어떤 작업을 스레드로 분리하면 무언가 좋은 방법이 나올 것입니다. 그런 방법에 대해서는 다른 책이나 강좌를 참고하세요. &lt;/P&gt;
&lt;P&gt;이번엔 프로세스가 아닌 스레드를 이용하여 에코 서버를 한번 만들어 보도록 합시다. 모든 문제를 해결할 수 있지는 않지만 공부하는 차원에서는 유용할 것입니다.%%% 유닉스에서는 POSIX라는 표준이 있습니다. 여기에는 스레드에 대한 내용이 있는데 그것이 pthread입니다. &lt;/P&gt;
&lt;H2 id=header30&gt;POSIX Thread&lt;/H2&gt;
&lt;H3 id=header31&gt;Thread vs Process&lt;/H3&gt;
&lt;P&gt;각 클라이언트를 다루기 위해 새로운 프로세스를 하나 만드는 것은 비용이 많이 듭니다. 그 내용을 살펴보면, &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;프로세스가 하나 생성될 때마다 운영체제는 메모리, 스택, 파일/소켓 식별자들 및 기타를 포함한 부모 프로세스의 전체 상태를 복사 
&lt;LI&gt;Thread들은 같은 프로세스 내의 멀티태스킹을 허용함으로써 이러한 비용을 감소. 새로 생성된 Thread는 부모와 같은 주소공간(코드 및 데이터)을 공유하고, 부모의 상태를 복제할 필요성 배제 
&lt;LI&gt;프로세스 복제이후 부모와 자식간에 정보를 주고받기 위해 프로세스간 통신(IPC) 필요 (자식으로부터 부모로 정보를 되돌리는 것은 더욱 많은 작업을 요구) &lt;/LI&gt;&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;프로세스 중의 모든 Thread가 공유하는 것 
&lt;UL&gt;
&lt;LI&gt;프로세스 지시 사항 
&lt;LI&gt;대부분의 데이터 
&lt;LI&gt;공개된 파일들(Ex 지정 번호들) 
&lt;LI&gt;신호 처리기와 신호 배치들 
&lt;LI&gt;사용자와 그룹 ID &lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;각 Thread 자신만이 갖는 것 
&lt;UL&gt;
&lt;LI&gt;Thread ID 
&lt;LI&gt;프로그램 계수기와 스택 지시자를 포함한 레지스터의 조합 
&lt;LI&gt;(지역변수와 반환 주소를 위한) stack 
&lt;LI&gt;errno 
&lt;LI&gt;신호 선별 
&lt;LI&gt;우선순위 &lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;이와 같이 비교 될 수 있습니다. &lt;/P&gt;
&lt;H3 id=header32&gt;Basic Thread Functions&lt;/H3&gt;
&lt;P&gt;거의 모든 pthread 함수는 성공하면 0을 리턴하고 실패하면 0이 아닌 값을 리턴 합니다. 그러나 errno 변수는 설정하지 않는 것이 특징입니다. 밑의 pthread 함수들은 모두 여기에 따른다고 생각하시면 됩니다. &lt;/P&gt;
&lt;P&gt;pthread를 사용하기 위해서는 밑의 해더를 추가해야 합니다. &lt;/P&gt;&lt;PRE&gt;#include &amp;lt;pthread.h&amp;gt;

int pthread_create( pthread_t * threadID,        // Thread ID, (unsigned int)
                    const pthread_attr_t * attr, // Thread 속성, NULL Default
                    void * ( * func )( void * ), // 입구함수
                    void * arg );                // 여러 인자를 전달할 때, structure 이용
&lt;/PRE&gt;
&lt;P&gt;스레드를 생성합니다. 첫 번째 인자는 스레드가 생성되면 그 스레드의 ID가 저장되는 변수이고, 두 번째 인자는 여러 가지 속성(우선순위나 스텍 사이즈 등을 말합니다.)을 나타냅니다. default로 하려면 NULL을 전달 하면 됩니다. 세 번째 인자는 스레드의 입구 함수(스레드가 시작되는 함수, 스레드가 할 역할을 기술해놓은 함수)입니다. 스레드가 실행되면 그 함수를 실행합니다. 입구함수의 형태는 반드시 &lt;/P&gt;&lt;PRE&gt;void * ThreadMain( void * arg );
&lt;/PRE&gt;
&lt;P&gt;위와 같은 형태여야 합니다. 그리고 마지막은 스레드 입구함수의 인자로 전달될 변수입니다. &lt;/P&gt;&lt;PRE&gt;void pthread_exit ( void * status ); // 리턴할 값
&lt;/PRE&gt;
&lt;P&gt;Thread 중단합니다. 만일 Thread가 분리되지 않으면 Thread ID와 리턴 값은 종결 프로세스의 다른 Thread에 의하여 나중까지 pthread_join에 남겨집니다. Thread가 종결 될 때에는 객체가 사라지므로 status 는 호출 Thread에 지역적인 변수를 지정하면 안됩니다. &lt;/P&gt;&lt;PRE&gt;int pthread_join ( pthread_t tid, void ** status );
&lt;/PRE&gt;
&lt;P&gt;tid가 가리키는 Thread가 종료할 때까지 위의 함수를 호출한 Thread의 수행을 멈춥니다. 만약 status가 NULL이 아니면 tid의 리턴 값은 status가 가리키는 영역에 저장됩니다. &lt;/P&gt;&lt;PRE&gt;pthread_t pthread_self ( void );
&lt;/PRE&gt;
&lt;P&gt;Thread 자신의 Thread ID 리턴 합니다. 이 값은 pthread_create() 로 얻은 스레드 ID와 동일합니다. &lt;/P&gt;&lt;PRE&gt;int pthread_detach ( pthread_t tid );
&lt;/PRE&gt;
&lt;P&gt;Thread 상태가 부모의 개입 없이도 종료 시 즉시 해제합니다. 주로 pthread_detach ( pthread_self() ); 로 사용합니다. &lt;/P&gt;
&lt;P&gt;보다 더 자세한 사항은 &lt;A class=con_link href=&quot;http://www.joinc.co.kr/modules.php?name=News&amp;amp;file=article&amp;amp;sid=118&amp;amp;mode=nested&quot; target=_blank&gt;&lt;FONT color=#111188&gt;Joinc의 Pthread API Reference&lt;/FONT&gt;&lt;/A&gt;를 참고하세요. &lt;/P&gt;
&lt;H3 id=header33&gt;TCP Echo Server를 위한 클라이언트당 Thread 멀티태스킹 Source&lt;/H3&gt;&lt;PRE&gt;/****** TCPEchoServer_Thread.c *******/

#include &quot;TCPEchoServer.h&quot;
#include &amp;lt;pthread.h&amp;gt; // for POSIX threads

void * ThreadMain(void * arg); // Main program of a thread

// Structure of arguments to pass to client thread
struct ThreadArgs
{
        int clntSock;
};

int main(int argc, char * argv[])
{
        int servSock;
        int clntSock;
        unsigned short echoServPort;
        pthread_t threadID;
        struct ThreadArgs * threadArgs;

        if(argc != 2)
        {
                fprintf(stderr, &quot;Usage: %s &amp;lt;Server Port&amp;gt;
&quot;, argv[0]);
                exit(1);
        }

        echoServPort = atoi(argv[1]);

        servSock = CreateTCPServerSocket(echoServPort);

        for(;;)
        {
                clntSock = AcceptTCPConnection(servSock);

                // Create memory for client argument
                if((threadArgs =
                   (struct ThreadArgs *) malloc(sizeof(struct ThreadArgs)))
                    == NULL)
                        DieWithError(&quot;malloc() failed&quot;);

                threadArgs-&amp;gt;clntSock = clntSock;
                // Create thread
                if(pthread_create(&amp;amp;threadID, NULL, ThreadMain,
                    (void *) threadArgs) != 0)
                        DieWithError(&quot;pthread_create() failed&quot;);
                printf(&quot;with thread %ld
&quot;, (long int) threadID);
        }
}

void * ThreadMain(void * threadArgs)
{
        int clntSock;
        // Guarantees that thread resource are deallocated upon return
        pthread_detach(pthread_self());

        clntSock = ((struct ThreadArgs *) threadArgs)-&amp;gt;clntSock;
        free(threadArgs); // Deallocate memory for argument

        HandleTCPClient(clntSock);

        return (NULL);
}
&lt;/PRE&gt;
&lt;P&gt;TCP 관련 소스는 앞의 select() 예제 소스와 같으니 위의 소스를 보시면 되겠습니다. 소스코드의 컴파일은 &lt;/P&gt;&lt;PRE&gt; $ gcc -o TCPEchoServer-Thread TCPEchoServer_Thread.c -Wall -lpthread (FreeBSD 라면 -pthread)

&lt;/PRE&gt;
&lt;P&gt;로 하시면 됩니다. &lt;/P&gt;
&lt;P&gt;소켓 부분은 에코 서버와 거의 같으니 스레드 부분만 보도록 하겠습니다. &lt;/P&gt;&lt;PRE&gt;pthread_create(&amp;amp;threadID, NULL, ThreadMain, (void *) threadArgs);
&lt;/PRE&gt;
&lt;P&gt;이 부분이 스레드를 생성하는 함수입니다. 입구함수 인자로 여기에서는 소켓번호 하나만 전달합니다. 그런데 전달되는 구조체를 &lt;/P&gt;&lt;PRE&gt;struct ThreadArgs
{
    int clntSock;
};
&lt;/PRE&gt;
&lt;P&gt;이렇게 선언해 놓았습니다. 물론 소켓번호만 전달해도 상관없습니다. 그런데 만약 여러 가지 정보를 전달하려고 하면 인자가 하나뿐이니 하나만 전달할 수 있습니다. 아니면 전역 등의 방법을 사용해야 합니다. 그런데 스레드 입구함수의 인자가 void * 형이기 때문에 이런 구조체를 만들어서 구조체의 포인터를 전달하면 여러 인자를 전달 할 수 있게 됩니다. &lt;/P&gt;
&lt;P&gt;그리고 소스를 보면 전달될 인자를 동적 메모리 할당을 하였는데 반드시 이렇게 해야 합니다. 만약 지역변수로 전달하게 되면 어떻게 될까요? 스레드는 서로 경쟁하며 실행됩니다. 그러니까 정확히 어느 것이 먼저 실행될지는 아무도 모르는 것입니다. 그래서 지역변수로 선언해 놓았다면 스레드가 실행되어 인자가 참조되기 전에 스레드 함수를 호출한 곳이 먼저 종료되었다면 인자의 변수는 잘못된 메모리를 가리키고 있는 것이 되어 버립니다. 그래서 잘못된 결과를 이르게 하는 것이죠. 그리고 스레드 입구함수에서 인자의 메모리를 해제했습니다. 이것도 위와 비슷합니다. 만약에 스레드 함수를 호출한 곳에서 메모리를 해제한다면 지역변수와 똑같은 결과를 낳게 됩니다. &lt;/P&gt;
&lt;P&gt;위 소스는 부족한 소스입니다. 만약 서버가 종료된다면 생성했던 스레드가 확실히 종료되었는지 그런 것을 알 수 없기 때문이죠. 물론 소멸되겠지만요. 안전하게 스레드가 종료되었는지 알고 나서 서버를 닫는 것이 더욱 좋을 것입니다. &lt;/P&gt;
&lt;P&gt;위의 스레드의 소스는 하나의 처리를 스레드에게 맡김으로써 여러 사용자를 받을 수 있게 하였습니다. 프로세스를 생성하는 것도 이와 비슷합니다. Pthread_create() 대신 fork()함수를 이용해서 프로세스를 만들면 됩니다. 앞에서 select()와 스레드에 대해서 알아 봤습니다. 그럼 이 두 개를 결합하여 만드는 것은 어떨까요? 그런 것은 채팅 서버를 한번 만들어 보시면서 하면 좋은 예가 될 것 같습니다. &lt;/P&gt;
&lt;H2 id=header35&gt;관련링크&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A class=con_link href=&quot;http://www.joinc.co.kr/modules.php?name=News&amp;amp;file=article&amp;amp;sid=118&amp;amp;mode=nested&quot; target=_blank&gt;&lt;FONT color=#111188&gt;Joinc.co.kr의 pthread API 레퍼런스&lt;/FONT&gt;&lt;/A&gt; - Joinc의 윤상배님의 글의 링크입니다. 
&lt;LI&gt;&lt;A class=con_link href=&quot;http://kldp.org/Translations/html/Socket_Programming-KLDP/Socket_Programming-KLDP.html&quot; target=_blank&gt;&lt;FONT color=#111188&gt;BeeJ&apos;s Guide to Network Programming&lt;/FONT&gt;&lt;/A&gt; - 한글 번역 문서입니다. &lt;/LI&gt;&lt;/UL&gt;&lt;/div&gt;</content>
                  <category term="async i/o"/>
            <category term="blocked"/>
            <category term="Network"/>
            <category term="nonblock"/>
            <category term="select()"/>
            
   </entry>
   <entry>
      <title>C++ Makefile Library</title>
      <id>http://www.textyle.kr/746</id>
      <published>2010-06-09T18:26:34+09:00</published>
      <updated>2010-06-09T18:26:34+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.textyle.kr/746"/>
      <link rel="replies" type="text/html" href="http://www.textyle.kr/746#comment"/>
      <author>
         <name>우와신난다</name>
                  <uri>http://alloe.tistory.com</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;br /&gt;
Library 배치 순서도 무지 중요하다...&lt;br /&gt;
&lt;br /&gt;컴파일은 되지만 제대로 동작안하는 문제가 발생하기도 한다..&lt;br /&gt;
그걸로 이틀 고생!&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
-lcommon -lclucene &lt;br /&gt;
과&amp;nbsp;&lt;br /&gt;
-lclucene -lcommon&lt;br /&gt;
&lt;br /&gt;위의 두가지는 엄청난 차이... 컴파일은 잘되고 실행도 잘 되지만 원하는대로 동작해주지 않는다.&lt;br /&gt;
assign이 제대로 되지 않는다던지 등등 많은 것들이 ㅠ&lt;br /&gt;
&lt;br /&gt;컴파일러가 빙시가 된듯한 느낌...&lt;br /&gt;
&lt;br /&gt;조심하자&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>intercept stdout/stderr of another process</title>
      <id>http://www.textyle.kr/745</id>
      <published>2010-05-21T00:04:59+09:00</published>
      <updated>2010-05-21T00:04:59+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.textyle.kr/745"/>
      <link rel="replies" type="text/html" href="http://www.textyle.kr/745#comment"/>
      <author>
         <name>우와신난다</name>
                  <uri>http://alloe.tistory.com</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;br /&gt;
1 . strace -ff -e write=1,2 -s 1024 -p PID 2&amp;gt;&amp;amp;1 | grep &quot;^ |&quot; | cut -c11-60 | sed -e &apos;s/ //g&apos; | xxd -r -p&lt;br /&gt;
&lt;br /&gt;2 . strace -ff -e trace=write -e write=1,2 -p SOME_PID&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>Show linux version</title>
      <id>http://www.textyle.kr/744</id>
      <published>2010-05-17T14:07:23+09:00</published>
      <updated>2010-05-17T14:07:23+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.textyle.kr/744"/>
      <link rel="replies" type="text/html" href="http://www.textyle.kr/744#comment"/>
      <author>
         <name>우와신난다</name>
                  <uri>http://alloe.tistory.com</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;br /&gt;
&amp;nbsp;lsb_release -a&lt;br /&gt;&lt;/div&gt;</content>
                  
   </entry>
</feed> 
