<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
	<channel>
		<title>sjang&#039;s blog 재미있는 네트워크 세상</title>
		<link>http://ilovelinux.org/sjang/</link>
		<description>장성재의 개인 블로그입니다.</description>
		<language>ko</language>
		<pubDate>Thu, 22 Oct 2009 14:32:08 +0900</pubDate>
		<generator>Textcube 1.5.3.1 : Adamantine</generator>
		<image>
		<title>sjang&#039;s blog 재미있는 네트워크 세상</title>
		<url>http://ilovelinux.org/sjang/attach/1/1368020251.jpg</url>
		<link>http://ilovelinux.org/sjang/</link>
		<width>129</width>
		<height>122</height>
		<description>장성재의 개인 블로그입니다.</description>
		</image>
		<item>
			<title>성남시 분당구 서현, 수내, 분당구청 잔디밭</title>
			<link>http://ilovelinux.org/sjang/81</link>
			<description>점심 먹으로 가면서 찍어봤습니다.&lt;br /&gt;날씨도 화창(좀 덥지)하고...&lt;br /&gt;&lt;br /&gt;이런 날씨에 찍으니 외국의 한가한 곳과 비교해도 손색이 없네.&lt;br /&gt;&lt;br /&gt;
&lt;img src=http://farm4.static.flickr.com/3187/2731195266_e13d6962c7.jpg /&gt;&lt;br /&gt;&lt;br /&gt;
&lt;img src=http://farm4.static.flickr.com/3049/2731193124_7aab112e9d.jpg /&gt;&lt;br /&gt;&lt;br /&gt;
&lt;img src=http://farm4.static.flickr.com/3098/2730361649_6d7393200b.jpg /&gt;&lt;br /&gt;&lt;br /&gt;
&lt;img src=http://farm4.static.flickr.com/3237/2730361951_f102aae5d8.jpg /&gt;&lt;br /&gt;&lt;br /&gt;
&lt;img src=http://farm4.static.flickr.com/3283/2730362301_4147afdd92.jpg /&gt;&lt;br /&gt;&lt;br /&gt;
&lt;img src=http://farm4.static.flickr.com/3075/2730363005_44fbcde7d7.jpg /&gt;&lt;br /&gt;&lt;br /&gt;
&lt;img src=http://farm4.static.flickr.com/3136/2730405921_7ecd21c7cc.jpg /&gt;&lt;br /&gt;&lt;br /&gt;
</description>
			<category>잡다한사진들</category>
			<author>(sjang)</author>
			<guid>http://ilovelinux.org/sjang/81</guid>
			<comments>http://ilovelinux.org/sjang/81#entry81comment</comments>
			<pubDate>Mon, 04 Aug 2008 14:26:30 +0900</pubDate>
		</item>
		<item>
			<title>소켓에서 발생하는 이벤트 감지의 기준. edge trigger와 level trigger</title>
			<link>http://ilovelinux.org/sjang/80</link>
			<description>&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://blog.ilovelinux.org/2009/10/edge-trigger-level-trigger.html&quot; target=&quot;_blank&quot;&gt;http://blog.ilovelinux.org/2009/10/edge-trigger-level-trigger.html&lt;/a&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;br /&gt;먼저, 쉬운것부터...&lt;br /&gt;&lt;br /&gt;레벨트리거: 소켓버퍼에 데이터가 들어있으면 무조건 이벤트가 발생하는 트리거이다. 즉, 소켓에서 read 할 수 있는 데이터가 1바이트 이상 있을때 이벤트가 발생했다고 리턴해준다. 여기서 1바이트라고 했지만 그 기준을 소켓옵션설정을 통해 조정할 수 있는 것으로 알고 있다. 이것을 조정하면 10바이트 이상일 경우에만 이벤트가 발생하는 것으로 기준을 설정할 수도 있다. (select(), poll() 등이 레벨트리거에 속한다.)&lt;br /&gt;&lt;br /&gt;에지트리거: 소켓버퍼의 데이터가 들어오는 시점을 알려주는 이벤트 트리거이다. 소켓버퍼가 비어 있다가 상대방으로부터 버퍼에 데이터가 들어오면 이때 이벤트가 발생한 것으로 간주한다. 들어온 데이터를 어플리케이션에서 read 하고 안하고는 무관하다. 즉, 에지트리거에서 이벤트가 발생했고(데이터가 들어왔고), 어플리케인션에서 read 하지 않더라도 그 이후에 다른 데이터가 추가로 들어오면 에지트리거는 이벤트가 발생했다고 리턴하게 된다. (epoll(), kqueue() 등이 에지트리거에 속한다. 이것들은 설정에 따라 레벨트리거로도 사용할 수 있다.)&lt;br /&gt;&lt;br /&gt;일반적으로.... 에지트리거가 대량의 접속시에 더 나은 응답속도를 제공한다.&lt;br /&gt;(이벤트 처리가 빠르다.)&lt;br /&gt;&lt;br /&gt;이해를 돕기 위해서 그림하나 추가해 본다.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://ilovelinux.org/sjang/attach/1/1189368970.jpg&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;223&quot; width=&quot;450&quot; /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;에지트리거를 다룰 때 주의점:&lt;br /&gt;에지트리거를 통해 이벤트 받았고 read 작업을 해야하는데, 이 시점에 read 할 수 있는 모든 데이터를 read 해야한다. 왜냐하면, 에지트리거는 데이터 유입에 대한 이벤트이므로 추가로 데이터 유입이 없으면 이벤트가 오지 않으므로 이번 이벤트를 통해 read를 할 때 다음에 다시 이벤트가 온다는 보장이 없으므로 이 시점에 읽을 수 있는 모든 데이터를 read 해야만 정상적인 처리가 된다. 어플리케이션의 read 버퍼가 작아서 꽉찬 상태로 리턴되면 이것을 다른 버퍼에 저장해 두고, 나머지를 다시 소켓으로부터 read 해야한다. 더 읽을 것이 없을때까지 계속 read 해야 한다. 이번에 read를 다 하지 않으면 영원히 다시 read할 이벤트가 오지 않을 수 있기 때문이다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;</description>
			<category>프로그래밍</category>
			<author>(sjang)</author>
			<guid>http://ilovelinux.org/sjang/80</guid>
			<comments>http://ilovelinux.org/sjang/80#entry80comment</comments>
			<pubDate>Tue, 25 Mar 2008 14:36:36 +0900</pubDate>
		</item>
		<item>
			<title>자체 제작 epoll 라이브러리(echo server 예제 포함)</title>
			<link>http://ilovelinux.org/sjang/79</link>
			<description>&lt;br /&gt;&lt;a href=&quot;http://blog.ilovelinux.org/2009/10/epoll-echo-server.html&quot; target=&quot;_blank&quot;&gt;http://blog.ilovelinux.org/2009/10/epoll-echo-server.html&lt;/a&gt;&lt;br /&gt;최신내용은 위 주소를 방문하세요.&lt;br /&gt;&lt;br /&gt;=============================================================&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;a class=&quot;extensionIcon&quot; href=&quot;http://ilovelinux.org/sjang/attachment/1297952911.gz&quot;&gt;&lt;img src=&quot;http://ilovelinux.org/sjang/image/extension/gz.gif&quot; /&gt; sjang_epoll_lib.tar.gz&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;C로 만든 echo server 이다.&lt;br /&gt;최고 성능이라고 평가받는 epoll()를 사용하였다.&lt;br /&gt;accept()를 사용하는 서버소켓은 Level Trigger를 사용하고, 클라이언트와 연결된 소켓은 Edge Trigger를 사용하였다. Non-blocking 소켓을 다루는 기본 방법에 대해서도 첨부된 예제를 통해 배울 수 있다.&lt;br /&gt;&lt;br /&gt;첨부된 파일은 epoll를 다루는 라이브러리를 제작하고, 그것을 사용하는 예제로 echo server를 제작한 것이다. 라이브러리를 통해 epoll에서 소켓을 어떻게 등록하고 해제하는지 알 수 있다.&lt;br /&gt;&lt;br /&gt;아래에 echo server의 구현 코드를 보였다.&lt;br /&gt;&lt;br /&gt;여기서 몇몇 에러처리가 빠져있는데, Non-blocking 소켓의 read에서 EAGIN 에러처리와 소켓 연결이 끊기는 이벤트를 감시하지 않은 것, 그리고 read 시에 버퍼를 넘었을 경우에 수신한 내용을 다른 곳에 저장하고 계속 read 해야 하는 것 등등...&lt;br /&gt;(Edge Trigger를 사용할 경우에는 read 시에 모두 읽어와야 한다. 왜냐하면, 다시 이벤트가 온다는 보장이 없으므로 이벤트가 왔을 때 모두 Read 해야 한다.)&lt;br /&gt;&lt;br /&gt;그러나, non-blocking 에서의 write 방법에 대해서는 정확하게 구현하였다.&lt;br /&gt;다음의 내용처럼....&lt;br /&gt;(non-blocking 소켓에서 write()를 수행할 경우에 write 하고자 하는 length만큼&lt;br /&gt;write가 되지 않을 수 있음을 알아야 합니다.&lt;br /&gt;예를 들어, 100바이트를 보내기 위해 write() 함수를 호출했을 때, 100바이트를 다 보내지 못하고 리턴됩니다. 리턴될 때, 보낸 length를 반드시 체크해야 합니다. 아마도 대부분의 경우에 100이 리턴되겠지요. 하지만, 네트웍이 바쁘거나 상태가 좋지 않거나 접속이 많은 경우에는 100보다 작은 숫자가 리턴됩니다. 원하는 바이트길이만큼 보내지 못한 것이지요. 이럴때에는 어떻게 해야할까요? 다시 write()를 바로 호출해야할까요? 그렇게 처리할 수도 있지만 바로 직전에 왜 100바이트를 모두 전송하지 못했는지를 이해한다면 그렇게 처리하는 것이 바람직하지 않습니다. 송신버퍼에 100바이트를 채울 여유가 없기때문에 100보다 작은 숫자가 리턴되는 것이기때문에 바로 다시 write()를 호출한다고해서 남은 바이트가 바로 전송된다는 보장이 없습니다.&lt;br /&gt;write()처리를 이벤트를 통해서 해야하는 이유가 여기에 있습니다. 100바이트를 모두 보내지 못했을 때, 그 소켓의 writable를 계속 체크해서 그 이벤트가 오면(송신버퍼에 빈공간이 생기면) 그 시점에 write()를 호출하면 되는 것이죠.&lt;br /&gt;따라서, non-blocking의 read/wirte는 소켓 이벤트의 결과에 따라 일괄적으로 처리를 해주어야 합니다.)&lt;br /&gt;&lt;br /&gt;write를 이벤트로 처리해야함은 필수사항이다. 대부분의 epoll 예제가 이 부분을 따로 처리하지 않았지만, 이는 네트웍상태가 좋지 않거나 클라이언트가 바쁘거나 등등의 이유로 원하는 크기를 전송할 수 없는 경우에 필수적인 에러처리이다.&lt;br /&gt;(스티븐 아저씨의 책에서도 명확하게 나와있음)&lt;br /&gt;&lt;br /&gt;라이브러리 및 예제에서 사용한 것들...&lt;br /&gt;&lt;br /&gt;1. TAILQ: 리눅스에서 기본제공하는 큐이다. 이것을 이용해서 echo 데이터 저장큐로 사용하였다. man page를 보면 친절한 예제와 함께 설명이 있다.&lt;br /&gt;2. myapp.h: 이 헤더파일과 echo_server.[ch] 파일을 함께 보기 바란다. 라이브러리를 사용하여 구현이 쉽도록 하기 위해서 echo 뿐만 아니라, 다른 자료구조를 도입하기 쉽도록 void * 를 이용하여 어플리케이션 원하는 자료구조를 쉽게 구성할 수 있게 하였다.&lt;br /&gt;3. 최대처리수: 최대 클라이언트 수를 소스안에 define를 통해 설정하게 하였다. 물론, 시스템 설정이 지원하는 최대개수 이내만 가능하다.&lt;br /&gt;&lt;br /&gt;아쉬운 점....&lt;br /&gt;doxygen를 이용하여 소스코드 문서를 만들어서 올릴 필요가 있겠다.. ^^&lt;br /&gt;&lt;br /&gt;echo_server.c 소스&lt;br /&gt;---------------------------------------------------------------------&lt;br /&gt;&amp;nbsp; 1 #include &quot;epollio.h&quot;&lt;br /&gt;&amp;nbsp; 2 #include &quot;socket_util.h&quot;&lt;br /&gt;&amp;nbsp; 3 #include &quot;myapp.h&quot;&lt;br /&gt;&amp;nbsp; 4&lt;br /&gt;&amp;nbsp; 5 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;&amp;nbsp; 6 #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;&amp;nbsp; 7 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;&amp;nbsp; 8 #include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;&amp;nbsp; 9 #include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;&amp;nbsp;10 #include &amp;lt;sys/socket.h&amp;gt;&lt;br /&gt;&amp;nbsp;11 #include &amp;lt;arpa/inet.h&amp;gt;&lt;br /&gt;&amp;nbsp;12&lt;br /&gt;&amp;nbsp;13 #include &quot;echo_server.h&quot;&lt;br /&gt;&amp;nbsp;14&lt;br /&gt;&amp;nbsp;15&lt;br /&gt;&amp;nbsp;16 #define MAX_CLIENT 1000&lt;br /&gt;&amp;nbsp;17&lt;br /&gt;&amp;nbsp;18 int recv_count = 0;&lt;br /&gt;&amp;nbsp;19 int send_count = 0;&lt;br /&gt;&amp;nbsp;20&lt;br /&gt;&amp;nbsp;21 static void reset_myapp_data(myapp_data_t *myapp_data)&lt;br /&gt;&amp;nbsp;22 {&lt;br /&gt;&amp;nbsp;23 &amp;nbsp; &amp;nbsp; echo_data_t *echo_data = (echo_data_t *)myapp_data-&amp;gt;data;&lt;br /&gt;&amp;nbsp;24&lt;br /&gt;&amp;nbsp;25 &amp;nbsp; &amp;nbsp; close(myapp_data-&amp;gt;socket_fd);&lt;br /&gt;&amp;nbsp;26 &amp;nbsp; &amp;nbsp; myapp_data-&amp;gt;socket_fd = -1;&lt;br /&gt;&amp;nbsp;27&lt;br /&gt;&amp;nbsp;28 &amp;nbsp; &amp;nbsp; memset(echo_data-&amp;gt;client_ip, 0, sizeof(echo_data-&amp;gt;client_ip));&lt;br /&gt;&amp;nbsp;29 &amp;nbsp; &amp;nbsp; memset(echo_data-&amp;gt;in_msg, 0, sizeof(echo_data-&amp;gt;in_msg));&lt;br /&gt;&amp;nbsp;30 &amp;nbsp; &amp;nbsp; memset(echo_data-&amp;gt;out_msg, 0, sizeof(echo_data-&amp;gt;out_msg));&lt;br /&gt;&amp;nbsp;31 &amp;nbsp; &amp;nbsp; echo_data-&amp;gt;in_msg_len = 0;&lt;br /&gt;&amp;nbsp;32 &amp;nbsp; &amp;nbsp; echo_data-&amp;gt;out_msg_len = 0;&lt;br /&gt;&amp;nbsp;33 &amp;nbsp; &amp;nbsp; echo_data-&amp;gt;sent_len = 0;&lt;br /&gt;&amp;nbsp;34 }&lt;br /&gt;&amp;nbsp;35&lt;br /&gt;&amp;nbsp;36&lt;br /&gt;&amp;nbsp;37 void init_myapp_data_members(myapp_data_t *myapp_data)&lt;br /&gt;&amp;nbsp;38 {&lt;br /&gt;&amp;nbsp;39 &amp;nbsp; &amp;nbsp; reset_myapp_data(myapp_data);&lt;br /&gt;&amp;nbsp;40 }&lt;br /&gt;&amp;nbsp;41&lt;br /&gt;&amp;nbsp;42&lt;br /&gt;&amp;nbsp;43 int init_myapp_data(myapp_data_t **mydata, int max_client)&lt;br /&gt;&amp;nbsp;44 {&lt;br /&gt;&amp;nbsp;45 /*&amp;nbsp; myapp_data_t *myapp_temp;*/&lt;br /&gt;&amp;nbsp;46 /*&amp;nbsp; echo_data_t *echo_temp;*/&lt;br /&gt;&amp;nbsp;47 &amp;nbsp; &amp;nbsp; int i;&lt;br /&gt;&amp;nbsp;48&lt;br /&gt;&amp;nbsp;49 &amp;nbsp; &amp;nbsp; for(i = 0; i &amp;lt; max_client; i++)&lt;br /&gt;&amp;nbsp;50 &amp;nbsp; &amp;nbsp; {&lt;br /&gt;&amp;nbsp;51 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if ((mydata[i] = (myapp_data_t *)malloc(sizeof(myapp_data_t))) == NULL)&lt;br /&gt;&amp;nbsp;52 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;br /&gt;&amp;nbsp;53 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return -1;&lt;br /&gt;&amp;nbsp;54 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;&amp;nbsp;55&lt;br /&gt;&amp;nbsp;56 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* 응용 데이터 공간을 queue 공간의 데이터 포인터에 할당 */&lt;br /&gt;&amp;nbsp;57 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if ((mydata[i]-&amp;gt;data = (echo_data_t *)malloc(sizeof(echo_data_t))) == NULL)&lt;br /&gt;&amp;nbsp;58 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;br /&gt;&amp;nbsp;59 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return -1;&lt;br /&gt;&amp;nbsp;60 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;&amp;nbsp;61 /* &amp;nbsp; &amp;nbsp;&amp;nbsp; mydata[i]-&amp;gt;data = (echo_data_t *)echo_temp;*/&lt;br /&gt;&amp;nbsp;62 /* &amp;nbsp; &amp;nbsp;&amp;nbsp; printf(&quot;myapp data Pointer [%x]\n&quot;, mydata[i]);*/&lt;br /&gt;&amp;nbsp;63 /* &amp;nbsp; &amp;nbsp;&amp;nbsp; printf(&quot;echo data Pointer [%x]\n&quot;, mydata[i]-&amp;gt;data);*/&lt;br /&gt;&amp;nbsp;64&lt;br /&gt;&amp;nbsp;65 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mydata[i]-&amp;gt;socket_fd = -1;&lt;br /&gt;&amp;nbsp;66 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; init_myapp_data_members(mydata[i]);&lt;br /&gt;&amp;nbsp;67&lt;br /&gt;&amp;nbsp;68 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* 확보한 공간을 Queue 안에 넣는다. */&lt;br /&gt;&amp;nbsp;69 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (i == 0)&lt;br /&gt;&amp;nbsp;70 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;br /&gt;&amp;nbsp;71 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; TAILQ_INSERT_HEAD(&amp;amp;myapp_data_event_queue, mydata[i], mydata_next);&lt;br /&gt;&amp;nbsp;72 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;&amp;nbsp;73 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; else&lt;br /&gt;&amp;nbsp;74 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;br /&gt;&amp;nbsp;75 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; TAILQ_INSERT_TAIL(&amp;amp;myapp_data_event_queue, mydata[i], mydata_next);&lt;br /&gt;&amp;nbsp;76 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;&amp;nbsp;77 &amp;nbsp; &amp;nbsp; }&lt;br /&gt;&amp;nbsp;78 &amp;nbsp; &amp;nbsp; return 0;&lt;br /&gt;&amp;nbsp;79 }&lt;br /&gt;&amp;nbsp;80&lt;br /&gt;&amp;nbsp;81 static int recv_msg(int fd, echo_data_t *echo_data)&lt;br /&gt;&amp;nbsp;82 {&lt;br /&gt;&amp;nbsp;83 &amp;nbsp; &amp;nbsp; int recv_len;&lt;br /&gt;&amp;nbsp;84 &amp;nbsp; &amp;nbsp; int buf_len = sizeof(echo_data-&amp;gt;in_msg) - 1;&lt;br /&gt;&amp;nbsp;85 &amp;nbsp; &amp;nbsp; recv_len = recv(fd, echo_data-&amp;gt;in_msg, buf_len, 0);&lt;br /&gt;&amp;nbsp;86 &amp;nbsp; &amp;nbsp; if (recv_len &amp;lt; 0)&lt;br /&gt;&amp;nbsp;87 &amp;nbsp; &amp;nbsp; {&lt;br /&gt;&amp;nbsp;88 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* non-blocking 소켓이므로 여기서 errno 체크해야함 */&lt;br /&gt;&amp;nbsp;89 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return -1;&lt;br /&gt;&amp;nbsp;90 &amp;nbsp; &amp;nbsp; }&lt;br /&gt;&amp;nbsp;91 &amp;nbsp; &amp;nbsp; if (recv_len == 0) /* 끊어진 소켓 */&lt;br /&gt;&amp;nbsp;92 &amp;nbsp; &amp;nbsp; {&lt;br /&gt;&amp;nbsp;93 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return -1;&lt;br /&gt;&amp;nbsp;94 &amp;nbsp; &amp;nbsp; }&lt;br /&gt;&amp;nbsp;95 &amp;nbsp; &amp;nbsp; echo_data-&amp;gt;in_msg_len = recv_len;&lt;br /&gt;&amp;nbsp;96 &amp;nbsp; &amp;nbsp; recv_count++;&lt;br /&gt;&amp;nbsp;97 &amp;nbsp; &amp;nbsp; printf(&quot;in msg = [%s]\n&quot;, echo_data-&amp;gt;in_msg);&lt;br /&gt;&amp;nbsp;98 &amp;nbsp; &amp;nbsp; printf(&quot;in msg len = [%d]\n&quot;, echo_data-&amp;gt;in_msg_len);&lt;br /&gt;&amp;nbsp;99&lt;br /&gt;100 &amp;nbsp; &amp;nbsp; return 0;&lt;br /&gt;101 }&lt;br /&gt;102&lt;br /&gt;103 static int send_msg(int fd, echo_data_t *echo_data)&lt;br /&gt;104 {&lt;br /&gt;105 &amp;nbsp; &amp;nbsp; int sent_len;&lt;br /&gt;106&lt;br /&gt;107 &amp;nbsp; &amp;nbsp; printf(&quot;send buf = [%s]\n&quot;, echo_data-&amp;gt;out_msg + echo_data-&amp;gt;sent_len);&lt;br /&gt;108 &amp;nbsp; &amp;nbsp; sent_len = send(fd, echo_data-&amp;gt;out_msg + echo_data-&amp;gt;sent_len, echo_data-&amp;gt;out_msg_len - echo_data-&amp;gt;sent_len, 0);&lt;br /&gt;109 &amp;nbsp; &amp;nbsp; if (sent_len &amp;lt; 0)&lt;br /&gt;110 &amp;nbsp; &amp;nbsp; {&lt;br /&gt;111 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; printf(&quot;send_msg error\n&quot;);&lt;br /&gt;112 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return -1;&lt;br /&gt;113 &amp;nbsp; &amp;nbsp; }&lt;br /&gt;114 &amp;nbsp; &amp;nbsp; printf(&quot;sent len = [%d]\n&quot;, sent_len);&lt;br /&gt;115&lt;br /&gt;116 &amp;nbsp; &amp;nbsp; echo_data-&amp;gt;sent_len += sent_len;&lt;br /&gt;117&lt;br /&gt;118 &amp;nbsp; &amp;nbsp; return 0;&lt;br /&gt;119 }&lt;br /&gt;120&lt;br /&gt;121&lt;br /&gt;122 int echo_server_process(struct epoll_event *event)&lt;br /&gt;123 {&lt;br /&gt;124 &amp;nbsp; &amp;nbsp; myapp_data_t *myapp_data;&lt;br /&gt;125 &amp;nbsp; &amp;nbsp; echo_data_t *echo_data;&lt;br /&gt;126&lt;br /&gt;127 &amp;nbsp; &amp;nbsp; myapp_data = (myapp_data_t *)(event-&amp;gt;data.ptr);&lt;br /&gt;128 /*&amp;nbsp; printf(&quot;echo server myapp_data process Pointer [%x]\n&quot;, myapp_data); &amp;nbsp;&amp;nbsp; */&lt;br /&gt;129 &amp;nbsp; &amp;nbsp; echo_data = (echo_data_t *)(myapp_data-&amp;gt;data);&lt;br /&gt;130 /*&amp;nbsp; printf(&quot;echo server echo_data process Pointer [%x]\n&quot;, echo_data);&amp;nbsp; */&lt;br /&gt;131&lt;br /&gt;132 &amp;nbsp; &amp;nbsp; if (event-&amp;gt;events &amp;amp; EPOLLIN)&lt;br /&gt;133 &amp;nbsp; &amp;nbsp; {&lt;br /&gt;134 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (recv_msg(myapp_data-&amp;gt;socket_fd, echo_data) &amp;lt; 0)&lt;br /&gt;135 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;br /&gt;136 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; printf(&quot;recv msg error\n&quot;);&lt;br /&gt;137 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return -1;&lt;br /&gt;138 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;139 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; printf(&quot;in msg copy [%s]\n&quot;, echo_data-&amp;gt;in_msg);&lt;br /&gt;140 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; strncpy(echo_data-&amp;gt;out_msg, echo_data-&amp;gt;in_msg, echo_data-&amp;gt;in_msg_len);&lt;br /&gt;141 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; printf(&quot;out msg [%s]\n&quot;, echo_data-&amp;gt;out_msg);&lt;br /&gt;142 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; echo_data-&amp;gt;out_msg_len = echo_data-&amp;gt;in_msg_len;&lt;br /&gt;143&lt;br /&gt;144 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* reset read buf */&lt;br /&gt;145 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; memset(echo_data-&amp;gt;in_msg, 0, sizeof(echo_data-&amp;gt;in_msg));&lt;br /&gt;146 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; echo_data-&amp;gt;in_msg_len = 0;&lt;br /&gt;147&lt;br /&gt;148 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; printf(&quot;writable on\n&quot;);&lt;br /&gt;149 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* writable check로 변경. */&lt;br /&gt;150 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (set_event_socket(&amp;amp;ed, myapp_data-&amp;gt;socket_fd, EVENT_WRITE, myapp_data, FD_MODIFY) &amp;lt; 0) /* echo server 이므로 EVENT_READ가 설정되어야 한다. */&lt;br /&gt;151 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;br /&gt;152 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fprintf(stderr, &quot;epoll set insertion error: fd=%d&quot;, myapp_data-&amp;gt;socket_fd);&lt;br /&gt;153 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return -1;&lt;br /&gt;154 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;155 &amp;nbsp; &amp;nbsp; }&lt;br /&gt;156 &amp;nbsp; &amp;nbsp; else if (event-&amp;gt;events &amp;amp; EPOLLOUT)&lt;br /&gt;157 &amp;nbsp; &amp;nbsp; {&lt;br /&gt;158 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (send_msg(myapp_data-&amp;gt;socket_fd, echo_data) &amp;lt; 0)&lt;br /&gt;159 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;br /&gt;160 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; printf(&quot;recv msg error\n&quot;);&lt;br /&gt;161 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return -1;&lt;br /&gt;162 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;163&lt;br /&gt;164 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; printf(&quot;out msg len = [%d]\n&quot;, echo_data-&amp;gt;out_msg_len);&lt;br /&gt;165 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if(echo_data-&amp;gt;out_msg_len == echo_data-&amp;gt;sent_len)&lt;br /&gt;166 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;br /&gt;167 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* reset write buf */&lt;br /&gt;168 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; memset(echo_data-&amp;gt;out_msg, 0, sizeof(echo_data-&amp;gt;out_msg));&lt;br /&gt;169 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; echo_data-&amp;gt;out_msg_len = 0;&lt;br /&gt;170 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; echo_data-&amp;gt;sent_len = 0;&lt;br /&gt;171&lt;br /&gt;172 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; send_count++;&lt;br /&gt;173&lt;br /&gt;174 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; printf(&quot;readable on\n&quot;);&lt;br /&gt;175 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* readable check로 변경. 즉, 받은데이터를 모두 echo 하기 전에 다시 받지 않음 */&lt;br /&gt;176 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (set_event_socket(&amp;amp;ed, myapp_data-&amp;gt;socket_fd, EVENT_READ, myapp_data, FD_MODIFY) &amp;lt; 0)&lt;br /&gt;177 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;br /&gt;178 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fprintf(stderr, &quot;epoll set insertion error: fd=%d&quot;, myapp_data-&amp;gt;socket_fd);&lt;br /&gt;179 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return -1;&lt;br /&gt;180 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;181 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;182 &amp;nbsp; &amp;nbsp; }&lt;br /&gt;183 &amp;nbsp; &amp;nbsp; return 0;&lt;br /&gt;184 }&lt;br /&gt;185&lt;br /&gt;186 int main()&lt;br /&gt;187 {&lt;br /&gt;188 &amp;nbsp; &amp;nbsp; int nfds;&lt;br /&gt;189 &amp;nbsp; &amp;nbsp; int listener;&lt;br /&gt;190 &amp;nbsp; &amp;nbsp; int client_fd;&lt;br /&gt;191 &amp;nbsp; &amp;nbsp; struct sockaddr_in local;&lt;br /&gt;192 &amp;nbsp; &amp;nbsp; socklen_t addrlen;&lt;br /&gt;193 &amp;nbsp; &amp;nbsp; int n;&lt;br /&gt;194&lt;br /&gt;195&lt;br /&gt;196&lt;br /&gt;197 &amp;nbsp; &amp;nbsp; myapp_data_t *new_myapp_data;&lt;br /&gt;198&lt;br /&gt;199&lt;br /&gt;200 &amp;nbsp; &amp;nbsp; myapp_data_t *myapp_data[MAX_CLIENT]; /* 현재 응용의 처리를 위한 데이터 구조체의 공간 확보 */&lt;br /&gt;201&lt;br /&gt;202 &amp;nbsp; &amp;nbsp; TAILQ_INIT(&amp;amp;myapp_data_event_queue);&lt;br /&gt;203&lt;br /&gt;204 &amp;nbsp; &amp;nbsp; if (init_myapp_data(myapp_data, MAX_CLIENT) &amp;lt; 0)&lt;br /&gt;205 &amp;nbsp; &amp;nbsp; {&lt;br /&gt;206 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; printf(&quot;init echo data error\n&quot;);&lt;br /&gt;207 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return -1;&lt;br /&gt;208 &amp;nbsp; &amp;nbsp; }&lt;br /&gt;209&lt;br /&gt;210 &amp;nbsp; &amp;nbsp; if ( init_epoll(&amp;amp;ed, 10000) &amp;lt; 0 )&lt;br /&gt;211 &amp;nbsp; &amp;nbsp; {&lt;br /&gt;212 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; printf(&quot;epoll_init error!\n&quot;);&lt;br /&gt;213 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return -1;&lt;br /&gt;214 &amp;nbsp; &amp;nbsp; }&lt;br /&gt;215&lt;br /&gt;216 &amp;nbsp; &amp;nbsp; addrlen = sizeof(local);&lt;br /&gt;217&lt;br /&gt;218 &amp;nbsp; &amp;nbsp; listener = make_socket(10025);&lt;br /&gt;219 &amp;nbsp; &amp;nbsp; if (listener &amp;lt; 0)&lt;br /&gt;220 &amp;nbsp; &amp;nbsp; {&lt;br /&gt;221 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return -1;&lt;br /&gt;222 &amp;nbsp; &amp;nbsp; }&lt;br /&gt;223&lt;br /&gt;224 &amp;nbsp; &amp;nbsp; if (add_epoll_listen_socket(&amp;amp;ed, listener, EVENT_READ) &amp;lt; 0 )&lt;br /&gt;225 &amp;nbsp; &amp;nbsp; {&lt;br /&gt;226 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return -1;&lt;br /&gt;227 &amp;nbsp; &amp;nbsp; }&lt;br /&gt;228&lt;br /&gt;229 &amp;nbsp; &amp;nbsp; while(1)&lt;br /&gt;230 &amp;nbsp; &amp;nbsp; {&lt;br /&gt;231 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; printf(&quot;--------------------------\n&quot;);&lt;br /&gt;232 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; printf(&quot;recv count = [%d]\n&quot;, recv_count);&lt;br /&gt;233 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; printf(&quot;send count = [%d]\n&quot;, send_count);&lt;br /&gt;234 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; printf(&quot;--------------------------\n&quot;);&lt;br /&gt;235 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; nfds = epoll_event_monitor(&amp;amp;ed, -1);&lt;br /&gt;236 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (nfds &amp;lt; 0)&lt;br /&gt;237 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;br /&gt;238 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return -1;&lt;br /&gt;239 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;240 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; printf(&quot;returned event [%d]\n&quot;, nfds);&lt;br /&gt;241&lt;br /&gt;242 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; for(n = 0; n &amp;lt; nfds; ++n)&lt;br /&gt;243 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;br /&gt;244 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if(ed.events[n].data.fd == listener)&lt;br /&gt;245 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;br /&gt;246 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; new_myapp_data = (myapp_data_t *)get_new_mydata();&lt;br /&gt;247 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; client_fd = accept(listener, (struct sockaddr *) &amp;amp;local, &amp;amp;addrlen);&lt;br /&gt;248 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if(client_fd &amp;lt; 0)&lt;br /&gt;249 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;br /&gt;250 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; perror(&quot;accept&quot;);&lt;br /&gt;251 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; continue;&lt;br /&gt;252 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;253&lt;br /&gt;254 /* &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; printf(&quot;new_myapp_data Pointer [%x]\n&quot;, new_myapp_data);*/&lt;br /&gt;255 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (set_event_socket(&amp;amp;ed, client_fd, EVENT_READ, new_myapp_data, FD_ADD) &amp;lt; 0) /* echo server 이므로 EVENT_READ가 설정되어야 한다. */&lt;br /&gt;256 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;br /&gt;257 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fprintf(stderr, &quot;epoll set insertion error: fd=%d&quot;, client_fd);&lt;br /&gt;258 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return -1;&lt;br /&gt;259 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;260 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;261 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; else&lt;br /&gt;262 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;br /&gt;263 /* &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; printf(&quot;ed event Pointer 1[%x]\n&quot;, &amp;amp;ed.events[n]);*/&lt;br /&gt;264 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (echo_server_process(&amp;amp;ed.events[n]) &amp;lt; 0)&lt;br /&gt;265 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;br /&gt;266 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* delete 추가 */&lt;br /&gt;267 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; myapp_data_t *myapp_data_temp = (myapp_data_t *)ed.events[n].data.ptr;&lt;br /&gt;268 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; reset_myapp_data(myapp_data_temp);&lt;br /&gt;269 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* 다시 queue로 반환한다. */&lt;br /&gt;270 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; TAILQ_INSERT_TAIL(&amp;amp;myapp_data_event_queue, myapp_data_temp, mydata_next);&lt;br /&gt;271 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;272 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;273 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;274 &amp;nbsp; &amp;nbsp; }&lt;br /&gt;275 &amp;nbsp; &amp;nbsp; return 0;&lt;br /&gt;276 }&lt;br /&gt;277&lt;br /&gt;&lt;br /&gt;---------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;</description>
			<category>프로그래밍</category>
			<author>(sjang)</author>
			<guid>http://ilovelinux.org/sjang/79</guid>
			<comments>http://ilovelinux.org/sjang/79#entry79comment</comments>
			<pubDate>Tue, 25 Mar 2008 09:41:59 +0900</pubDate>
		</item>
		<item>
			<title>03/04 2. An opportunity to get your foot in the door.</title>
			<link>http://ilovelinux.org/sjang/78</link>
			<description>&lt;P&gt;2. &amp;nbsp; An opportunity to get your foot in the door.&lt;/P&gt;
&lt;br /&gt;
&lt;P&gt;Al is complaining to Megan that he is doing such monotonous work now.&lt;/P&gt;
&lt;br /&gt;
&lt;P&gt;Megan &amp;nbsp; &amp;nbsp; So, how’s the internship going?&lt;/P&gt;
&lt;P&gt;Al &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Ugh, talk about a waste of time.&lt;/P&gt;
&lt;P&gt;Megan &amp;nbsp; &amp;nbsp; You were really excited about it last time I talked with you.&lt;/P&gt;
&lt;P&gt;Al &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; I was until I actually started. I’m just a gofer. I make coffee and run errands. I thought I’d actually get a chance to do some work.&lt;/P&gt;
&lt;P&gt;Megan &amp;nbsp; &amp;nbsp; It can’t be that bad. Surely, you’re doing some interesting things.&lt;/P&gt;
&lt;P&gt;Al &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Not really. Unless you consider making photocopies interesting.&lt;/P&gt;
&lt;P&gt;Megan &amp;nbsp; &amp;nbsp; Keep your chin up. An internship is a good opportunity to get your foot in the door.&lt;/P&gt;
&lt;P&gt;Al &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; I don’t know. I was thinking about quitting.&lt;/P&gt;
&lt;P&gt;Megan &amp;nbsp; &amp;nbsp; No, don’t do that. I know it seems dull to just do office work, but remember that this is your opportunity to network.&lt;/P&gt;
&lt;P&gt;Al &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; How am I going to do that? Give resumes as I pass out coffee?&lt;/P&gt;
&lt;P&gt;Megan &amp;nbsp; &amp;nbsp; No, by showing them you are a hard worker. Think about when you graduate and apply for a job later. If they know you are a hard worker, then they’re more likely to give you a job.&lt;/P&gt;
&lt;P&gt;Al &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; You do have a point there. But it’s hard to be happy just doing such monotonous work.&lt;/P&gt;
&lt;P&gt;Megan &amp;nbsp; &amp;nbsp; If you really feel that way, why don’t you speak up? Ask your boss for the chance to help out, even if that means you need to spend more time there. &lt;/P&gt;
&lt;P&gt;Al &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; That’s not a bad idea.&lt;/P&gt;
&lt;P&gt;Megan &amp;nbsp; &amp;nbsp; Trust me. You won’t regret it.&lt;br /&gt;&lt;/P&gt;</description>
			<category>power english</category>
			<author>(sjang)</author>
			<guid>http://ilovelinux.org/sjang/78</guid>
			<comments>http://ilovelinux.org/sjang/78#entry78comment</comments>
			<pubDate>Thu, 20 Mar 2008 08:51:08 +0900</pubDate>
		</item>
		<item>
			<title>iso 만드는 프로그램</title>
			<link>http://ilovelinux.org/sjang/71</link>
			<description>&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://ilovelinux.org/sjang/attach/1/1061959775.jpg&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;184&quot; width=&quot;403&quot; /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;간편하게 iso 만들 수 있는 프로그램을 소개합니다.&lt;br /&gt;단, CD에 들어있을 때에만 그것을 iso로 만들 수 있습니다.&lt;br /&gt;&lt;br /&gt;For the latest version turn to: &lt;A href=&quot;http://www.lucersoft.com/&quot;&gt;http://www.lucersoft.com&lt;/A&gt;&lt;br /&gt;&lt;br /&gt;</description>
			<category>기타</category>
			<author>(sjang)</author>
			<guid>http://ilovelinux.org/sjang/71</guid>
			<comments>http://ilovelinux.org/sjang/71#entry71comment</comments>
			<pubDate>Sat, 04 Aug 2007 01:07:09 +0900</pubDate>
		</item>
	</channel>
</rss>

