Win32 API나 MFC와 마찬가지로 .NET Framework에서도 비동기 방식으로 소켓 통신을 하기 위한 방법을 제공한다. 그 방법은 MSDN 내에 비동기 서버 소켓 사용과 비동기 클라이언트 소켓 사용에 관한 아티클에 상세하게 소개 되어 있다.

이 글에서 소개하고자 하는 AsyncSocketClient와 AsyncSocketServer는 .NET Framework에서 제공하는 비동기 소켓을 좀 더 사용하기 쉽게 만든 일종의 Wrapper 라이브러리라고 할 수 있다. 물론, .NET Framework 자체에서 소켓을 좀 더 고수준화한 TcpClient와 TcpListener란 클래스도 제공하지만; 제약이 많다;

물론, Socket에서 제공하는 모든 부분까지 구현한 것은 아니고; Connect, Close, Send, Receive, Accept 정도만 제공하는 것으로 소스를 공개함으로써 누구나 수정, 재배포가 가능하도록 하였다(다시 말해서; 자기가 필요한 부분은 추가로 구현해서 써도 상관없다.); 하지만, 가급적이면 저의 흔적을 말살하지 않기를..ㅠㅠ;

아, 그리고 이 라이브러리는 100% TCP 기반으로 구현되어 있다; UDP는 제공하지 않는다;

이 라이브러리가 .NET Framework에서 제공하는 소켓 클래스보다 편리한 부분은 소켓에서 발생하는 Connect, Close, Accept, Error, Send, Receive 등을 이벤트화 하였기에; 폼이나 다른 클래스에서 소켓을 핸들링 하는 것이 쉬워졌다; 다시 말해서, 폼이나 클래스에서 이벤트 핸들러만 재정의하면 소켓 이벤트를 처리할 수 있다;

사용자 삽입 이미지

위 그림에서 알 수 있듯이, 본 라이브러리는 기본적으로 AsyncSocketClass란 하나의 부모 클래스와 클라이언트 소켓 파트를 구현한 AsyncSocketClient, 서버 소켓 파트를 구현한 AsyncSocketServer로 이루어져 있다;

자식 클래스들을 좀 더 자세히 살펴보면 다음과 같다;

사용자 삽입 이미지
AsyncSocketClient는 public method로 Connect, Close, Send, Receive가 지원된다; 하지만; Receive는 특수한 경우를 제외하고는 개발자가 직접 호출할 필요는 없다; (이 부분은 나중에 좀 더 자세하게 설명하도록 한다..) 왜냐하면; 기본적으로 연결이 성공하면 데이터 수신을 위해 자동적으로 수신 대기 상태가 되기 때문이다;

만약, 데이터 수신을 성공하면, OnReceive 이벤트를 재정의 하여, 이 이벤트 핸들러에서 수신한 데이터를 지지고 볶고 하면 된다.OnConnect, OnClose, OnSend 모두 같다;

아래는 AsyncSocketClient를 이용해 구현한 샘플 프로그램의 코드 일부(이벤트 재정의 부분)이다.
사용자 삽입 이미지

여기서 중요한 것은 AsyncSocketClient 생성자의 인자로 숫자 0이 들어갔는데; 이는 다수의 AsyncSocketClient 인스턴스들을 생성을 가졍했을 때, 각각을 식별하기 위한 ID라고 할 수 있다.

그리고 그 아래 OnConnect 이벤트 핸들러가 있는데;
인자로 object sender와 AsyncSocketConnectionEventArgs e가 들어간다.

sender는 AsyncSocketClient로 캐스팅해서 쓰면, 이벤트가 발생한 소켓 클라이언트 자신이다;
(AsyncSocketClient worker = (AsyncSocketClient)sender;)

AsyncSocketConnectionEventArgs는 이벤트가 발생한 소켓 클라이언트의 ID 등을 포함하고 있다;

사용자 삽입 이미지

OnReceive를 살펴보면 넘어오는 Event 인자가 소켓의 ID, 수신한 바이트 수(ReceivedBytes), 수신한 데이터(ReceivedData)가 포함되어 있음을 알 수 있다. 참고로 위의 코드는 수신한 데이터가 byte[] 타입이기 때문에, string으로 캐스팅하기 위한 Encoding.... 코드가 포함되어 있다.

그 다음 AsyncSocketServer로 넘어가면;

AsyncSocketServer는 public method로 Listen, Stop이 지원된다; 만약 Client의 접근이 Accept 되면, OnAccept 이벤트가 발생하므로, OnAccept 이벤트를 재정의 하여, Client를 처리하면 된다;

사용자 삽입 이미지

AsyncSocketServer에서 가장 중요한 부분은 클라이언트 소켓의 접속을 처리하는 OnAccept 부분이다.

OnAccept에서 넘어오는 Event 인자는 접속이 허가된 소켓(e.Worker) 인스턴스가 포함되어 있다;

따라서, OnAccept 이벤트 핸들러에서는 AsyncSocketClient를 그대로 이용하기 위해, 이벤트 핸들러 내의
첫 줄과 같은 코드가 필요하다; 또한; 클라이언트의 ID가 중복되지 않도록, 새로운 ID도 부여한다.

그리고 그 다음이 앞서 언급한 AsyncSocketClient가 Receive를 호출해야할 특수한 상황이다;
구현 방법에 따라서; 이 부분은 Accept 코드 내에서 처리할 수도 있었지만; 어짜피 개발자가 이벤트 핸들러 연결도 필요하기 때문에; 그냥 이렇게 구현하였다.

끝으로 새로 생성한 클라이언트 소켓들을 미리 정의한 이벤트 핸들러와 연결하는 코드들이 나오고;
끝으로 클라이언트 리스트에 Add한다. (다수의 클라이언트 접속 가능 예를 들기 위해서 이렇게 했음);

좀 더 편리한 개발을 위해서는; MSDN 수준의 Class Specification을 쓰고 싶었지만; 시간 및 기타 여건이 허락되지 않는 관계로 이만 줄임!

대신에 라이브러리 및 예제 소스를 공개하니; 이를 이용하면 되지 않을까... 무책임하게 생각해봅니다;

다운로드: http://www.nohungry.net/Data/AsyncSocket.zip
크리에이티브 커먼즈 라이센스
Creative Commons License

Trackback

Trackback Address :: http://www.nohungry.net/tt1/trackback/160

Comments

  1. 카논 2010/03/09 10:52

    좋은 정보 감사합니다.
    서버/클라에 대한 구현 팁을 좀더 알려주셧으면 하는..
    초보자에게 정말 많은 도움이 될거 같습니다.

    perm. |  mod/del. |  reply.
    • 노헝그리 2010/03/09 17:33

      저도 아는 것이 없지만; 매우 기초적인 내용으로 조금씩 쓰려고 생각 중이었습니다;

      날개발자지만; 명색이 직딩이다보니~ 잘 안되지만; 틈틈이 써보도록 하겠습니다~^^;

  2. 김용수 2010/03/31 18:34

    테스트를 해보왔는데...소켓에 대한 close가 안됩니다..ㅠㅠ
    이벤트가 발생을 안하네요

    perm. |  mod/del. |  reply.
  3. 김기범 2010/05/10 09:53

    위 코드의 경우,

    여러번 Send()를 날렸을 때

    onReceive() 이벤트가 byte[]가 중첩되어 발생하는 경우가 있는데요
    (접속상태가 좋지 못하거나, 지연되는 네트워크일때 더더욱)

    이것은 정상인 것인가요? 아니면 의도되지 않은 오류인가요?

    예) 10bytes를 빠르게 여러번 Send() ->

    onReceive() 에서 발생되는 이벤트가, 10, 10, 20, 10, 20, 30, 10 등

    중첩되어 발생되는 경우가 있음

    perm. |  mod/del. |  reply.
    • 노헝글이 2010/05/10 22:47

      제가 회사를 옮기고, 회사 보안 정책 상 회사에서 블로그나 데브피아에 글을 적을 수 없어 이제 확인합니다;

      소켓 통신에서는 10바이트를 보낸다고 항상 받는 쪽에서도 10바이트를 받는다고 보장할 수 없습니다.

      님의 말씀처럼 네트워크 지연이나 기타 원인으로 인해 당연히 중첩되어 받을 수 있습니다. 즉, 정상이라는 얘기입니다.

      따라서, 데이터를 받는 쪽은 버퍼(흔히 큐를 많이 이용합니다.)를 이용해서 데이터를 처리하고, 데이터를 보내는 쪽에서는 보낸 데이터들을 구분하기 위해 데이터에 STX, ETX와 같은 구분자를 붙여서 보내고는 합니다.

  4. 이민규 2010/05/19 11:29

    저도 Close할 때 오류가 나네요.

    perm. |  mod/del. |  reply.
  5. 이민규 2010/05/20 16:29

    Close 오류는 해결했는데,
    이제는 Close할 때 이전에 보냈던 hello가 또 보내지네요;;

    perm. |  mod/del. |  reply.

What's on your mind?

댓글 입력 폼
[로그인][오픈아이디란?]

[C#] Auto FTP Uploader

2010/03/03 15:29
사용자 삽입 이미지

 회사에서 맡은 프로젝트 중... 실시간으로 생성되는 데이터를 원격의 FTP 서버에 전송해야할 일이 생겼다.

 상용 FTP 클라이언트 프로그램에서 일종의 매크로 기능을 사용하면 이와 같은 기능을 대신할 수 있지만; 상용 프로그램을 쓰는 것도 부담 스럽고; 내가 원하는대로 커스터마이징 하는 것이 불가능해서 그냥 만들었다.

Auto FTP Uploader의 로직은 매우 심플하다; 특정 Source Folder를 설정하고, 업로드 할 FTP 주소와 계정 정보를 입력해둔 다. Auto FTP Uploader는 Source Folder의 Rename 이벤트를 감지하여, 이벤트가 발생하면, 원격 FTP 주소에 업로드 한다.

 Source Folder의 Create 이벤트를 감지할 경우, 파일 작성이 완료되는 시점을 알 수 없으므로, 데이터를 생성하는 부분에서 파일이 작성되는 시간 동안에는 확장자를 TMP로 만들고, 파일 작성이 완료되면 확장자를 DAT로 바꾸게 하였기에 Rename 이벤트를 감지하도록 했다. (Temp Folder와 Complete 폴더는 원격 FTP 서버의 요구 사항에 의해 만든 것으로 파일이 작성되면 원격 FTP 서버에 동일한 파일명의 Dummy File을 업로드 한다.)

 프로그램 자체는 뭐 특별한 기능은 없지만; .NET Framework를 이용하면 간단한 FTP를 구현하는 것은 일도 아니라는 생각이 든다. 또, C#을 처음 접하는 이들에게는 C#을 이해하는데 도움이 되지 않을까 생각한다.

 이 프로그램에 사용된 주요 프로그래밍 테크닉은 다음과 같다.

 1. 파일 입/출력
 2. FtpWebRequest 클래스의 사용법
 3. 간단한 Thread의 사용 예
 4. ManualResetEvent, Monitor를 이용한 동기화 기법
 5. 델리게이트(delegate)를 이용한 클래스 또는 폼 간의 이벤트 발생 및 전달

 코멘트가 상세히 포함되어 있지는 않지만; 복잡한 로직은 거의 없고, 가급적 모듈별로 분리하도록 노력하였기 때문에 크게 어려움은 없지 않을까 생각해본다...;

사용자 삽입 이미지

소스 다운로드 : http://www.nohungry.net/Data/FTPUploader.zip

수정 및 재배포 자유, 영리적 목적의 사용도 자유! 단, 출처만 밝혀주세요;
크리에이티브 커먼즈 라이센스
Creative Commons License

Trackback

Trackback Address :: http://www.nohungry.net/tt1/trackback/159

Comments

What's on your mind?

댓글 입력 폼
[로그인][오픈아이디란?]

 D/B에서 데이터를 가져오는 경우, 데이터를 저장 또는 변경하는 경우에 그 데이터가 많다면... 일반적인 동기 방식으로 처리할 경우, 프로그램에서는 매우 난감한 상황이 발생할 수 있다.

 데이터를 처리하기 전까지 소위 프로그램이 멍 때리는 상황... 다른 모듈의 동작까지 블럭(Block)이 되고, UI 마저 "응답 없음"이란 상태에 놓일 수 있다.

 이에 대한 해결책이 바로 비동기 방식으로 D/B를 처리하는 것이다.

 C# 아니 엄밀히 말하면 .NET에서는 데이터베이스 뿐만아니라 네트워크 등 다양한 경우에 대한 비동기 메소드(Method) 등을 지원한다. 데이터베이스 관련해서는 크게 ExecuteReader와 ExecuteNonQuery 동작에 대한 비동기 함수들을 지원한다. 두 함수의 차이는 SELECT와 같은 Transaction-SQL을 처리할 수 있는 함수라는 것과 UPDATE, INSERT, DELETE와 같은 Non-Transaction-SQL을 처리할 수 있는 함수라는 것이다.

 만약 앞서 설명한 함수들을 이용할 경우, 이 함수가 결과를 반환할 때 까지 나머지 모듈들은 블럭이 된다. 반면에, 이에 대한 비동기 함수들인 BeginExecuteReader-EndExecuteReader, BeginExecuteNonQuery-EndExecuteNonQuery를 사용하면 블럭이 되는 현상을 방지할 수 있다.

 함수의 간단한 사용 방법은 다음과 같다.

사용자 삽입 이미지

 모든 비동기 함수는 반드시 Begin~으로 시작하는 함수와 End~로 시작하는 함수가 쌍을 이루어야 된다.

간단한 설명을 위해 이 함수에 D/B Connection과 Close까지 포함되고, 데이터를 읽어오기 위한 코드도 포함되어 있지만.. 엄밀히 말하면 이들도 각각 분리되어야 한다.

 특히, D/B로 부터 읽어온 데이터를 처리하는 부분(Grid에 데이터를 넣든지, 그래프로 그리던지)은 별도의 함수로 구현해서 Thread로 처리하는 것이 바람직하다. 왜냐하면, 프로그램이 멍 때릴 정도로 읽어와야할 데이터가 많다면.. 필히 이 데이터를 처리하는 부분을 단순히 처리할 경우에도 단순히 문제가 될 수 있다.
크리에이티브 커먼즈 라이센스
Creative Commons License

Trackback

Trackback Address :: http://www.nohungry.net/tt1/trackback/148

Comments

What's on your mind?

댓글 입력 폼
[로그인][오픈아이디란?]

[C#] 자동 업데이트 프로그램

2009/07/29 16:37

사용자 삽입 이미지
 프로그램의 자동 업데이트 기능은 인터넷 보급율이 타의 추종을 불허하는 국내에서는 필수적인 요소가 되어 버렸다. V3, 알약 같은 백신은 물론이고, 곰플레이어 등 사용자 Application에도 모두 포함되어 있다.

2년 전쯤에 간단한 기능의 자동 업데이트 프로그램을 만든 적 있었는데; 지인들도 찾지 않는 내 유령 블로그에서 (사실 나도 거의 하지 않는다..) 가장 인기 게시물이었다; 그 프로그램과 관련해 질문도 많이 받고, 링크 복구 요청도 많이 받아... 마지막으로 다시 올린다.

아래 DLL과 자동 업데이트 프로그램은 Microsoft Visual Studio.NET 2005를 이용해 C#으로 개발하였으며, 사용한 모든 함수는 Microsoft .NET Framework 2.0에 포함되어 있다.

 일단 자동 업데이트 프로그램의 구성은 매우 심플하다.
(1) 프로그램 버전 체크를 위한 DLL과 Configuration 파일
- UpdateChecker.dll
- update.ini

(2) 프로그램 업데이트를 위한 자동 업데이트 프로그램과 Configuration 파일
- SmartUpdater.exe
- start.ini

 프로그램의 자동 업데이트 로직은 간단하다. (물론, 복잡하게 만들려면 복잡하게도 만들 수 있으나, 그건 각자의 특수성에 맞게 고민해야할 문제.)

STEP 1. 프로그램을 실행한다.

STEP 2. 업데이트 서버에 연결하여, 현재 프로그램의 버전과 업데이트 서버가 가지고 있는 업데이트 버전과 비교해서 최신 업데이트가 있으면, 자동 업데이트 프로그램을 실행하고, 현재 프로그램을 종료한다.

 물론, 간혹 이런 경우도 있다. 자동 업데이트 프로그램을 업데이트해야 되는 경우; 그 때는 실행하기 전 자동 업데이트 프로그램의 파일명을 rename해서 변경한 후, 실행하면 된다; 그리고 프로그램 업데이트 후, rename된 자동 업데이트 프로그램을 삭제하면 끝;

(1) 프로그램 버전 체크를 위한 DLL의 함수들
사용자 삽입 이미지

DLL의 함수는 달랑 3개다. (하나는 기본 생성자)

ReadConfigFile은 업데이트 서버의 주소와 버전 정보가 담긴 파일명이 저장된 Configuration 파일(update.ini)을 읽는다. 말이 거창하게 Configuration 파일이지, 실제로 파일을 열어보면 달랑 2줄의 내용이 들어있다.

라인 1: http://www.nohungry.net/UpdateServer/
라인 2: version.txt

라인 1은 Update 서버의 URL이고, (반드시 끝에 /를 붙여줘야 한다.)
라인 2는 버전 정보가 저장된 파일명이다.

IsNewUpdateExists는 인자(parameter)로 현재 프로그램의 버전과 업데이트 서버의 버전 정보 파일(http://www.nohungry.net/UpdateServer/version.txt)에 저장된 버전을 비교하여, 현재 프로그램의 버전이 구버전인 경우, true를 반환하고 아니면 false를 반환한다.

GetLastError는 UpdateCheck 시 발생한 에러 메시지를 반환한다. 예를 들면, 업데이트 서버를 연결할 수 없다거나, 새로운 업데이트 파일이 없다는 내용을 반환한다.

(2) 프로그램 업데이트를 위한 자동 업데이트 프로그램
 자동 업데이트 프로그램은 상기 업데이트 체크 DLL에서 새로운 업데이트가 존재할 경우, 호출되는 프로그램이다. 이 프로그램은 업데이트 서버에서 업데이트 파일들을 다운로드 받고, 설치하는 역할을 한다.

 자동 업데이트 프로그램의 Configuration 파일(start.ini) 역시 DLL과 마찬가지로 단순한 정보를 담고 있다.
라인 1: http://www.nohungry.net/UpdateServer/
라인 2: file_list.txt
라인 3: MyNewProgram.exe

라인 1은 업데이트 서버의 URL
라인 2는 업데이트 파일 목록이 저장된 파일명
라인 3은 업데이트 완료 후, 실행할 파일명

사실 업데이트 서버 URL이나 이런 것들은 보안을 생각한다면, 위에 예처럼 무식하게 텍스트 파일로 쓰는 것은 좋지 않다. 이러한 것들은 바이너리로 저장한다거나 아니면 Configuration 파일이 아닌 레지스트리에 쓴다거나 아니면 기타 각자의 아이디어를 이용하도록 하자.

앞서 언급한 DLL과 자동 업데이트 프로그램을 이용해, 내 프로그램에 자동 업데이트 기능을 구현해보자고 한다면, 다음과 같이 할 수 있다. (예외 처리나 기타 복잡한 내용은 빼고, 심플한 코드)

사용자 삽입 이미지

이 게시물에 언급한 모든 내용 및 소스 코드는 아래 링크에서 다운로드 가능합니다.
http://www.nohungry.net/Data/SmartUpdateChecker.zip

관련 게시물 주소
http://www.nohungry.net/tt1/34

이 소스를 그대로 쓰시든지 수정해서 상용으로 쓰시든지 모든 것이 자유입니다. 단, 수정 요청은 받지 않습니다.
또한, 이 소스를 이용해 발생한 어떠한 문제도 책임지지 않습니다.

끝으로 이 게시물의 소스를 다운로드 받아가시거나, 게시물 내용을 블로그에 퍼가시더라도... 댓글이나 출처는 꼭 남겨주세요!
크리에이티브 커먼즈 라이센스
Creative Commons License

Trackback

Trackback Address :: http://www.nohungry.net/tt1/trackback/147

Comments

  1. 지송 2009/08/21 11:21

    잘보고 갑니다.

    소스는 다운 받았습니다. ^^ 공부좀 해보려고요...

    수고하세요.

    perm. |  mod/del. |  reply.
  2. Lani 2009/09/09 11:12

    잘 보고 갑니다. 다운로드 기능 구현해야 하는데 참고할께요..

    perm. |  mod/del. |  reply.
  3. 감사해요 2009/11/10 23:09

    졸업작품하려는데 많은 도움이 되는거같네요 ㅎㅎ 감사합니다

    perm. |  mod/del. |  reply.
    • 노헝그리 2009/11/16 15:35

      별 말씀을...^^;

  4. SGP 2010/07/19 09:47

    다운로드 기능 구현하려고 서핑중에 우연히 발견했네요
    감사히 잘 사용하겠습니다

    perm. |  mod/del. |  reply.

What's on your mind?

댓글 입력 폼
[로그인][오픈아이디란?]

사용자 삽입 이미지

Visual Studio 2005로 작성한 멀쩡히 돌아가던 내 소스를 새로 설치한 PC에 옮겨서 빌드를 했더니, 저런 어처구니 없는 오류가 나왔다.

근데, 아무리 찾아봐도... 저런 파일은 없었다; 아.. 뭐지? Visual Studio 2005가 잘못 깔렸나?

구글을 찾아봐도 안 나온다; 범인은 바로... 아이콘(ico) 파일 때문이었다;

해결 방법은... 아래 그림과 같이 솔루션 탐색기에서 해당 프로젝트 명에서 우클릭한 후, 속성을 선택한다.

사용자 삽입 이미지

그리고 리소스에서 아이콘을 원래 있던 아이콘에서 기본 아이콘으로 빌드하니... 오류가 생기지 않았다.
사용자 삽입 이미지

문제가 발생한 원인은 이게 끝!

근데 도무지... 이게 왜! 생기는지는 나도 알 수 없다. 아이콘 파일도 해당 경로에 정확히 있는데 말이다;

혹시 아이콘이 잘못 만들어졌다면... 내 PC에서도 안되어야 하는데; 참;
크리에이티브 커먼즈 라이센스
Creative Commons License

Trackback

Trackback Address :: http://www.nohungry.net/tt1/trackback/144

Comments

What's on your mind?

댓글 입력 폼
[로그인][오픈아이디란?]

저도 특정 테이블에서 데이터를 가져오는 것이 아니라, 데이터를 재가공한 후, 크리스탈 레포트로 출력하는 형식이었는데,

다음과 같이 진행하였습니다..^^

우선 님이 크리스탈 레포트에 출력하고자 하는 형식의 데이터셋 파일(*.xsd)을 만드세요. 그러면 원래 마법사가 뜨면서 Connection String도 넣어라고 하고, 나오죠? 거기서 취소를 하고 도구상자에서 DataTable을 하나 끌어와서 만듭니다.

그 DataTable을 임의로 MyTable이라고 하기로 하죠.
그리고 ID랑 Name이란 2개의 칼럼을 만들었다고 가정하겠습니다..^^ 그리고 저장을 합니다.

그럼 이 xsd 파일은 크리스탈 리포트 형식(*.rpt) 파일의 기반이 됩니다.
그러면, CrystalReportSource와 CrystalReportViewer를 각각 생성하고, cs와 cv라고 명명했다고 하죠.

그럼 rpt파일은 xsd파일을 이용해서 생성된 것이고, cs는 이 rpt파일을 기반으로 생성됩니다. 이해가 되시나요?^^;;

cv의 보고서 소스는 바로 cs를 선택하시면 되겠죠.. 그럼.. 크리스털리포트뷰어에 ID와 Name으로 구성된 페이지가 나올겁니다..

그럼 이제 내용을 채워야겠죠.. 내용을 채우는 순서는 다음과 같습니다.

1. DataTable 타입의 객체를 CrystalReportSource에 바인딩시킨다.
2. CrystalReportViewer의 ReportSource에 CrystalReportSource를 할당한다.
3. 그리고 CrystralReportViewer를 Refresh한다.

그럼 먼저 DataTable 객체를 선언하고, 정의해보면..

DataTable dataSrc = new DataTable();

dataSrc.Columns.Add("ID");
dataSrc.Columns.Add("Name");

dataSrc.Rows.Add(new string[]{"23", "Michael Jordan"});
dataSrc.Rows.Add(new string[]{"10", "Pele"});

이렇게 하시면 됩니다..^^

그럼 이제 이 객체를 CrystalReportSource에 바인딩시켜야겠죠.
아까 CrystalReportSource를 생성하고, 이름을 cs로 했다고 했으니...

cs.ReportDocument.SetDataSource(dataSrc);
cs.DataBind();

하면 됩니다.. 그리고 CrystalReportViewer의 ReportSource에 cs를 할당하고, 보고서를 새로 그려주면 됩니다.

cv.ReportSource = cs;
cv.RefreshReport();

-끝-

너무 길게 그리고.. 두서없이 쓴 것 같네요..^^; 그럼 즐프하세요.

-------------------------------------------------------------------------------------------
내가 예전에 데브피아에 쓴 답글..
근데, 시간이 흘러.. 갑자기 나도 써야하니.. 기억이 안나서 찾는다고 고생했다..
그래서 내 블로그에 남겨둠..-_- 이 한심한 기억력이란.. 쯧-ㅁ-

크리에이티브 커먼즈 라이센스
Creative Commons License

Trackback

Trackback Address :: http://www.nohungry.net/tt1/trackback/104

Comments

  1. 2007/10/04 09:05

    예전에 크리스탈리포트 한다고 자료찾고 공부했던 기억이..ㅋ

    perm. |  mod/del. |  reply.
    • NOhungry 2007/10/04 15:43

      크리스탈리포트 좀 갈쳐주세요-ㅁ-

      아.. 갑자기 이걸 해야되는 상황인데.. DB에서 다른 것들은 다 되는데.. 이미지만 안 불러진다는 사실-ㅁ-!!!!

  2. 2007/10/05 09:08

    이미지경로로는 못불러오구 DB자체에 이미지를 바이너리형태로 저장해서 불러왔었던것 같아요 -0-;;
    너무 오래전에 했던것이라...;;

    perm. |  mod/del. |  reply.

What's on your mind?

댓글 입력 폼
[로그인][오픈아이디란?]

C#에 대한 생각...

2007/08/01 23:47

근래에 C#으로 5~6개의 프로젝트를 수행하면서 C#은 단지 Java와 C++을 짬뽕시켜놓은 특징없는 언어일뿐이라고 평가절하했던 나의 생각이 많이 바뀌었다.

프로그래머들에게 대체 불가의 언어로 여겨지는 C++과 8~90년대 급격한 성장을 해온 Java의 틈에 끼여 아직 C#이 차지하는 위치는 낮지만, 개인적으로 C#은 무궁무진한 장점을 가진 언어란 생각이 든다.

우선 C#에 대해 소개하자면, 앞서 언급한 것과 같이 C++과 Java를 교묘하게 섞어놓았다.
똑같이 .NET Framework를 기반으로 돌아가는 VB와는 달리, C#은 if, while, for 문이 C++과 정말 닮아있다. 물론, Java와도 정말 닮아있다.

또한, C#은 Java와 유사하게 .. 아니 표절이라고 해야하나?-ㅁ-; Garbage Collection을 지원한다. 따라서 특별한 경우를 제외하곤 프로그래머는 리소스 해제에 대해 신경 쓰지 않아도 된다. (하지만, 성능을 염두에 둔다면 가급적 Garbage Collection이 자주 발생하지 않게 프로그래밍 해야하지만!!)
포인터가 없다! (아니, 그냥 없다고 하면 그렇지만.. 없다고 봐도 무방하다고 하고 싶다.-ㅁ-)

Java와 마찬가지로 primitive type과 object type이 존재한다.
다시말하면, 정수를 다루는 타입이 기본적으로 int와 Integer 2가지가 제공된다. (물론, 역할은 다르지만..)

게다가, C#은 Windows Programming, Web Programming, PDA, Phone 등의 개발에 그대로 적용될 수 있다!

이 모든 것이 다 .NET Framework 때문이다. 따라서, .NET Framework는 Java Virtual Machine이 가지고 한 장점을 고스란히 가지고 있다고 볼 수 있다. (물론, 상이한 점도 존재하지만!)

그리고, Java보다 좋은 점..^^
UI 꾸미기가 마치 VB 만큼이나 쉽다. 고로, 생산성이 좋다! Java는 사실 좋은 툴로 프로그래밍한 기억이 전혀 없어서 그럴 수도 있지만.. 버튼을 생성하고, 이벤트 핸들러를 등록하는 작업이 아직도 악몽같다-_-

그러고보니, 학부 때도 처음에 C/C++ 보다 Java에 더 애착이 갔었던 과거를 생각하면... 난 이상하게도 Managed Code에 잘 이끌리는 것 같다-ㅁ-


물론, 그래도 회사의 주력 제품의 개발 언어가 C++이기 때문에 이 녀석에 대한 공부도 여전히 소홀할 수는 없다. 하지만, 근래에 C#에 대해 많은 수련을 거듭하면서 웹 프로그래밍도 어느 정도 가능하게 되었고.. 프로그래밍에 대한 다양하고 폭 넓은 사고를 할 수 있는 계기가 되고 있다는 생각이 든다.

C#을 공부하면서 드는 생각은..
축구에서도 멀티 플레이어를 강조하는 현대 시대에 더 이상, C/C++ 만 고집해서만은 안되겠다는 생각이 든다. (물론! C/C++이 소프트웨어 개발 분야에서 대체 불가능한 언어란 생각에는 변함이 없다^^)

크리에이티브 커먼즈 라이센스
Creative Commons License
TAG

Trackback

Trackback Address :: http://www.nohungry.net/tt1/trackback/98

Comments

  1. acaran 2007/08/04 00:33

    오... 역시 자넨 이것저것 많이 공부하시는구려~

    자네말처럼 C#이 C++과 Java의 장점을 섞어만들었다면 아주 쓸만하겠다는 생각이 드는군-_-

    생산력 면에서 극강이겠소~


    뭐, 적응의 문제겠지만 Java쓸때도 그렇고... 난 포인터가 없는 언어를 쓰면 왠지 손발이 묶인채로 프로그래밍을 하는 느낌이 들어서... 영 개운치가 않다오-_-

    남들 다 쉽다고 하는 비주얼베이직을 몇번이고 공부해볼까하다가 집어던진 이유가 아마도...
    포인터 없는거도 모자라, 변수형까지 지맘대로 흐느적거리는 것이었던거 같소-_-;;

    내 뇌구조가 특이한걸까-_-;;;

    perm. |  mod/del. |  reply.
    • NOhungry 2007/08/10 11:40

      으음.. 답글이 늦었네. 주위 사람들의 반응을 보면 자네의 뇌구조가 결코 평범하지 않지.ㅎ

      나도 사실 비베는 정말 난감하다오.ㅎ 예전에 학부 때 권교수 아래에서 프로젝트 할 때는 어쩔 수 없이 했었지만서도 말일세.ㅎ

      첨에 나도 C#을 할 때 포인터가 없어서 좀 당황스러웠다오. 하지만, 난 Java에도 익숙해서 그런지 몰라도, 곧 적응이 되더군.ㅎ

      아 그리고 C#에서 포인터를 완전히 쓸 수 없는건 아니라오, 안전하지 않지만, 지원은 하는걸로 알고 있소.

      관련 아티클을 읽어본 기억은 있지만, 굳이 권장하지 않는걸 쓸 필요가 없단 생각이 들어 그냥 기억에서 지웠소만.ㅎ

      암튼 주말에 만납세.ㅎ

What's on your mind?

댓글 입력 폼
[로그인][오픈아이디란?]

[C#] 메일 자동 발송 프로그램

2007/05/02 18:00
 하루에도 많게는 수백통씩 날아들어오는 스팸 메일의 시대에 살면서... 나 또한 그러한 범죄에 악용될 수 있는 프로그램을 만들어버렸다.

예전 아티클에도 나와있지만... 이번에도 회사 업무 차원에서 만들게 되었다. (그렇다고 우리 회사에서 스팸을 보내기 위해 만든 것이 아니다. 병역특례 관련해서 각 대학에 공문을 발송하기 위해 만들었다.)

이전과 달라진 점은...
SMTP를 설정하지 않아도 된다는 점이다. 왜냐하면 IIS를 설치하면 제공되는 ESMTP를 쓰기 때문이다.

따라서, 무료로 제공하는 SMTP를 찾기 위해 헤맬 필요가 없다. 자신 PC의 포트를 통해 발송하기 때문이다. 정확하게 기억은 안나지만.. 아마도 80번 포트?-ㅁ-; (기억이 안나는 이유는 2월쯤인가 만들었었다.)

급하게 부탁받아.. 하루 정도 걸려 만들었기 때문에, 자질구레한 예외는 가볍게(?) 무시해버린 센스를 발휘했다. 그래서, 무슨 버그가 발생할지 알 수 없다.

구현은 그 때와 마찬가지로 C#과 .NET Framework 2.0을 기반으로 했다.

주요기능
- 동일한 내용의 메일을 대량으로 발송
- 메일링 리스트 불러오기 및 저장 가능
- 메일링 리스트 추가, 삭제, 저장, 수정 가능
- 메일 내용 미리보기 기능(HTML로 작성된 메일을 브라우저에서 어떻게 보일까를 위해..)
- 첨부 파일 (용량 제한은 상대방 수신 메일 서버에서 허용하는 범위 만큼만)
- 메일 내용 불러오기 및 저장 가능
- 서명 첨부 가능
- 발송한 메일 로그 확인
[디자인적 측면은 전혀 고려하지 않은 유저 인터페이스]

[메일 내용 미리 보기]

비록 C#으로 구현하였지만.. Visual Studio 2005를 사용하는 사람이라면, C++, Visual Basic으로도 동일하게 구현가능하다.

부끄러워서 풀 소스 공개는 못하더라도.. 주요부분(ESMTP를 이용해 메일을 발신하는 부분 - 몇 줄 되지도 않고, 새로울 것도 없지만.. )은 공개 가능하다.

덧1) 이러한 포스트를 남기는 이유는.. 명색이 컴공 전공자로써.. 전공 얘기가 전무한 것이 부끄러버서 한거라고는 말 못함-ㅁ-

덧2) 회사에서 병역특례(전문연구요원)를 구하고 있음. 전공은 전산쪽 계열이며 가능함. (물론, 프로그래밍 가능자).. 덧붙이면 2007년 8월 졸업자에 한함. 관심있는 분들은 연락바람.
크리에이티브 커먼즈 라이센스
Creative Commons License

Trackback

Trackback Address :: http://www.nohungry.net/tt1/trackback/78

Comments

  1. 2007/05/03 11:29

    2008년 2월 졸업생도 싸게 구하실수 있다고.. 어케 말씀 전해바바바바~ ^^;;

    perm. |  mod/del. |  reply.
    • NOhungry 2007/05/03 12:54

      맹// ㅎㅎ 안타깝지만, 2008년 2월 졸업생은 내년을 기약해야겠지~ 이번 TO는 2007년에 소진시켜야 한다.ㅋ 안그럼, 내년에 TO가 안나오걸랑~

  2. 열정 2007/05/03 20:06

    내년부터 보충역 산업기능요원을 없애버린다는 소문이 있소 -_-
    이러다가 전문연구요원도 없어지는거 아닌가 몰라 ㅋㅋ

    perm. |  mod/del. |  reply.
    • NOhungry 2007/05/03 23:47

      음~ 전문연구요원은 그렇게 쉽게 없어지지 않을거야. 이공계 장려해야 하니깐.

  3. acaran 2007/05/04 22:18

    다음엔 자동 야근, 자동 주말특근 프로그램좀 하나 짜주게 ㅠ_ㅠ

    perm. |  mod/del. |  reply.
  4. 안재명 2007/07/27 09:47

    이거 소스가 어디있나염?? ^^

    perm. |  mod/del. |  reply.
  5. 가을아이 2007/08/21 15:25

    만드시 프로그램 보구 공부할려구 합니다... 소스 주실수 있으신지요...?

    perm. |  mod/del. |  reply.
    • NOhungry 2007/09/05 00:50

      안재명, 가을아이// 답글이 늦었습니다. 정말 죄송합니다.

      언젠가 따로 이 내용과 관련해 포스팅을 하고, 거기에 소스를 공개하려고 했는데, 귀차니즘으로 점점 미루어지고 있네여..

      맘같아서는 저 허접한 소스를 백방에 공개하고 싶습니다면, 현재로선 회사 업무용으로 사용되고 있어서 전체 소스 공개는 사실 불가능할 것 같네여. 죄송합니다.

  6. 비밀방문자 2008/02/13 15:34

    관리자만 볼 수 있는 댓글입니다.

    perm. |  mod/del. |  reply.

What's on your mind?

댓글 입력 폼
[로그인][오픈아이디란?]

[C#] Cross Thread Problem

2006/10/20 17:35

서두는 제외하고, 바로 예를 들어 설명하도록 하겠다. (편의 상 반말로...)

A란 프로그램은 여러 개의 Thread가 돌고 있다. 그 중 Thread T1은 B란 프로그램과 소켓 통신을 위해 사용되는데, T1은 B에서 전송하는 메시지를 처리한다. 그리고 처리된 메시지는 바로 텍스트 박스 컨트롤에 표시된다.

프로그래머는 단순히, 다음과 같이 코드를 썼다.

ThreadFunc T1()
{
    while(1){
           ....
           // B가 보낸 메시지를 받는다.
           int nMessage = GetSocketMessage();
           
          // 메시지를 텍스트 박스에 표기한다.
           txtBoxControl.Text = nMessage.ToString();            
    }
}
    
그랬더니 Cross Thread Problem이란 메시지가 뜨며, 프로그램이 제대로 수행될 수 없다고 나온다. 과연, Cross Thread Problem이란 무엇인가 (물론, 위의 코드가 정확히 Cross Thread Problem을 발생하는 것은 아니다.. 하지만 그럴 가능성을 내재하고 있는 코드라고 할 수 있다.)?!

MSDN에 따르면,
전문적인 프로그램은 응답성 있는 사용자 인터페이스를 유지하기 위해 worker thread들을 사용하게 된다(*hyperthreading 또는 Multiple CPU들의 최대화를 위해서..). 하지만, .NET에서 이 문제는 특별히 쉬운 문제가 아니다, 왜냐면, Windows Forms 컴포넌트들은 thread safe 하지 않기 때문이다(특별히 번역할 말이 없어서-_-.. Thread들에 대해 안전하지 않다 정도의 뉘앙스일까나..?).

.NET의 어떤 버젼에서는 thread들 내부에 GUI 컴포넌트의 함수를 호출하려고 할 경우, 예외를 발생시킬 수 있다. 하지만, 종종 내가 의도한 바와 다른 이상한 결과를 내는 것으로 끝날 수도 있다(예외는 발생 안했지만, 내가 의도한 결과와 다르게 나올 수 있다는 말이다).

해결 방법은?!
만약, 다른 thread로부터 GUI 컴포넌트를 호출하고 싶다면, 직접적으로(directly) 호출할 수는 없다. 대신에 컨트롤 클래스로부터 상속받은 invoke 함수를 통해 간접적으로(indirectly) 실행하고자 하는 컴포넌트의 함수를 호출할 수 있다.

다른 invoke 함수와는 달리, 컨트롤 클래스의 invoke 함수는 데이터 corruption을 피해 호출을 동기화할 수 있도록 보장해준다.

컨트롤의 invoke 함수를 호출하기 위해 필요한 것은 invoke 함수의 인자로써 호출하고자 하는 함수를 delegate로 작성해서 넘겨야 한다. 그리고 invoke 함수의 인자로 넘어가는 함수에 필요한 인자는 object 배열로 넘겨야 한다.

예를 통해서 살펴보자!
예제 프로그램은 다른 프로그램에서 소켓을 통해 날려주는 탭 컨트롤의 인덱스를 받아, 현재 프로그램의 탭을 변경하는(그러니까 탭 화면을 바꾸는) 기능을 포함하고 있다.

즉, 다른 프로그램에서 전송하는 메시지를 처리하는 함수가 Thread로 동작하고 있고, 이 Thread 내부에서 탭 컨트롤의 탭을 변경하는 상황이 발생하기 때문에, Cross Thread 문제가 발생하였다(참고로 말하면, 각 탭에도 탭에 어떠한 데이터를 표현하기 위한 다른 Thread들도 동작하고 있기 때문에, Cross Thread 문제가 매우 발생하기 쉬운 구조다.)

예제 코드를 보면!
우선 WaitMessage()란 함수는 다른 프로그램에서 Socket을 통해 전송하는 메시지를 처리하기 위한 Thread 함수다. 이 때 받아들이는 메시지는 현재 프로그램의 탭 컨트롤의 인덱스이다. 이 Thread 내부에서 탭 컨트롤의 탭을 변경하기 위해 바로, SelectTab() 함수를 호출할 경우, Cross Thread 문제로 인한 Exception이 발생한다.

DoWork()는 이러한 문제를 회피하기 위한 함수다. 자세한 내용은 아래 코드를 보면서 얘기하자.
                                           ....

  DoWork() 함수는 앞서 WaitMessage() 함수에서 다른 프로그램으로부터 전송받은 탭 인덱스를 파라미터로 받아 현재 프로그램의 탭을 변경하는 역할을 수행한다. 또한, DoWork() 함수는 앞서 언급한 Cross Thread 문제를 회피하기 위해 컨트롤 클래스의 Invoke 함수를 사용하는데, Invoke 함수를 사용하기 위해서는 필연적으로 delegate를 선언해야 한다(delegate에 대한 상세한 내용은 다른 기술 문서를 참조하기 바란다.)

예제에선 ChangeTab이란 delegate를 선언하고, DoWork() 함수에서 사용한다.
DoWork() 함수에선 탭 컨트롤의 InvokeRequired 속성을 체크해 true일 경우, Invoke() 함수를 사용한다.
앞서 선언한 delegate의 파라미터로 탭 컨트롤의 SelectTab() 함수를 넘기고, Invoke() 함수에는 delegate와 SelectTab() 함수에 필요한 인자(탭 인덱스)를 함께 파라미터로 넘긴다.



결론
지금까지 간략하게 Cross Thread Problem에 대해 기술해보았다. 보다 깊은 내용보다는 왜 문제가 발생하고, 어떻게 해결하느냐에 대한 기술만 해놓았기 때문에, 보다 자세한 내용을 알고 싶다면, MSDN을 참조하기 바란다.


덧, hyperthreading에 대한 보다 자세한 내용은 http://blog.naver.com/subellia1?Redirect=Log&logNo=100011680762의 article을 참조하기 바란다.

크리에이티브 커먼즈 라이센스
Creative Commons License

Trackback

Trackback Address :: http://www.nohungry.net/tt1/trackback/39

Comments

  1. acaran 2006/10/21 16:13

    아이고 머리야-_- 무슨말인지 하나도 몬알아묵겠네 그랴~ -_-

    perm. |  mod/del. |  reply.
  2. 조병수 2008/06/18 16:02

    모르는 부분을 잘 설명해 주셔서 감사해요~~

    perm. |  mod/del. |  reply.
  3. 김형준 2009/12/31 11:17

    감사! ^^

    perm. |  mod/del. |  reply.
  4. 최익필 2010/02/08 14:21

    완전 감사합니다!

    perm. |  mod/del. |  reply.

What's on your mind?

댓글 입력 폼
[로그인][오픈아이디란?]

우리는 근래에 자동 업데이트 프로그램에 둘러쌓여 산다.
Windows XP는 시도 때도 없이.. 새로운 패치가 나왔다고 자동 업데이트 하겠냐고 물어보고.-ㅁ-
카트라이더에 로그인 하면.. 알아서 새로운 버젼이 나왔다고 설치한다.

프로그램 개발자에게 있어 새로운 버젼이 나왔는데, 이걸 사용자에게 어떻게 전해주느냐는 중요한 문제다. 사실 사용자에게 새버젼이 나왔을 때 마다 전화해서 알려줄 수도 없으니..

자동 업데이트 프로그램.. 간지나는 디자인이 어디서 본 듯 하다.



내가 맹근 자동 업데이트 프로그램의 흐름은 심플하다.
프로그램을 실행시키면, 프로그램은 업그레이드 서버에 연결하고, 프로그램 내에 이식된 업데이트 체커는 프로그램의 현재 버젼을 읽어와 업그레이드 서버의 업그레이드 정보 파일(단순한 txt 파일)에서 읽은 버젼과 비교한다.

프로그램의 버젼 정보



비교한 결과, 현재 버젼보다 새로운 버젼이 존재하면.. 자동 업데이트 프로그램을 호출해 업그레이드 서버로부터 최신 파일들을 다운 받아 설치한다.

내가 구현한 자동 업데이트 프로그램의 스펙 및 개략적인 소개를 하면 다음과 같다.
(1) SmartUpdater.exe - C#으로 구현했으며, .NET Framework 2.0이 설치되어 있어야 돌아간다. (소스는 공개하지 않음.)
(2) UpdateCheck.h & UpdateCheck.cpp - 사실 이 소스는 내가 구현한 것이 아니라,  CodeProject란 곳의 Alexander Bischofberger란 아저씨가 구현한 소스를 내 입 맛에 맡게 약간의 수정을 거쳤다.
(3) UpdateChecker.exe - 앞 서 언급한 (1)과 (2)를 이용해 만든 예제 프로그램이다. (소스도 공개한다.)



UpdateCheck.h 파일을 열면 위 그림과 같다.

UpdateCheck.h


수정할 부분은 대략 IDS_UPDATE 부터 IDS_UPDATE_NO 정도까지가 되겠다.
IDS_UPDATE는 업그레이드 정보가 담긴 파일의 URL이다. 이 파일의 형식은 다음과 같다.


앞에 3과 4는은 Major Version과 Minor Version이다. 그러니까 내 프로그램의 버젼이 1.0.0.1 이라면 앞의 1과 0이 Major Version과 Minor Version이라 할 수 있다. 그리고 젤 마지막의 URL은 원래 원저작자는 업데이트 페이지로 연결하도록 구현하였는데, 난 그냥 업데이트 프로그램을 로딩시켜서 설치하도록 하였기 때문에, 마지막 URL은 의미가 없다. 그리고 각 항목의 구분자(delim)는 "|(\ 위에 있는 녀석)" 이다.

그 아래 IDS_UPDATE_AVAILABLE은 새로운 버젼을 찾았을 경우, 설치하겠냐고 묻는 문구이다. 그 이하는 읽어보면 대충 감이 올 것이다. (입맛에 맞게 바꾸도록 하자.)

아, 그리고 참고로 #include <wininet.h> 하면 링크 에러가 뜰 것이다-ㅁ-.. "wininet.lib version.lib" 녀석들을 참조하도록 해야된다.

UpdateCheck 사용


그리고, 실제 사용은.. MyProgramApp 내에 InitInstance() 함수 안에서 위의 내용을 써주면 된다. 이 때 _T("SmartUpdater.exe")는 내가 개발한 자동 업데이트 프로그램(업데이트를 위한 웹 서버에서 Update File List를 읽어와 Update File들을 Local PC로 다운로드 하는 역할을 함.)을 호출하는 부분이므로, 각자가 구현한 자동 업데이트 프로그램을 추가해주면 된다.

어떻게 자동 업데이트 프로그램을 구현하였는지는.. 다음 문서에서 자세히 소개하도록 할 예정이다. (전체 소스를 공개하지는 않지만.. 핵심 부분은 알 수 있다.)

모든 소스 코드를 공개하였습니다. 수정 및 재배포도 모두 허용합니다. 대신, 수정 요청이나 디버깅 요청은 사절입니다.

다운로드 : http://www.nohungry.net/Data/AutoUpdateChecker.zip
참조: http://www.codeproject.com/cpp/updatecheck.asp
크리에이티브 커먼즈 라이센스
Creative Commons License
TAG ,

Trackback

Trackback Address :: http://www.nohungry.net/tt1/trackback/34

Comments

  1. acaran 2006/09/21 11:18

    오~ 간지가 좔좔 흐르는 프로그램이구려~! 근데 혹시라도 업데이트 하는 그 프로그램 자체를 업데이트 할일이 생기면 어쩌는가?-_- 역시 몇가지 꽁수를 추가하는 수 밖에 없겠지? -_-

    perm. |  mod/del. |  reply.
  2. NOhungry 2006/09/21 11:28

    원래 그런걸 피하려면.ㅋ ActiveX로 맹글어서~ 웹에서 설치하도록 해야겠지.ㅋ
    근데 내 생각에는.. 업데이트 목록에 업데이트 된 업데이트 프로그램도 추가해놓고.ㅋ 같이 다운 받으면 되지 않겠나?ㅋㅋ

    perm. |  mod/del. |  reply.
  3. acaran 2006/09/21 19:27

    다운받으면 현재 파일이 열려 있어서 그냥 받으면 안될꺼 같은데-_- 파일명을 약간 다르게 하거나 다른 경로에 받은후, 재실행 되게 만들어서 그때 덮어쓰게 하면 되겠구려-_-

    perm. |  mod/del. |  reply.
  4. kwangho 2009/02/12 23:15

    smartclient 구동방식과 다른건가요?

    perm. |  mod/del. |  reply.
    • 노헝그리 2009/02/17 12:00

      스마트 클라이언트를 커스터마이징 했다고 보시면 되겠습니다..^^;

  5. 컴매니아  2009/04/20 11:07

    안녕하세요.. 이번에 자동업데이트 부분을 구현하려고 하는데 자료가 없어 여기저기

    검색하다가 오게 되었습니다.

    그런데.. 링크가 깨져 있군요.. 혹시 메일로 보내주실수 있을까요? kbgyhy@naver.com으로

    괜찮다면 부탁드립니다.

    perm. |  mod/del. |  reply.
  6. 명랑한 2009/05/19 11:44

    안녕하세요..

    저도 요즘 자동업데이트 관련 자료를 찾고있었는데.

    다운로드 받는 링크가 깨져있네요, 제게도 가능하시면 보내주세요

    chungi68@hanmail.net

    perm. |  mod/del. |  reply.
  7. 김철령 2009/07/14 15:13

    포스트에 언급하신 자동 업데이트 기능을 구현중에 있는데요..
    몇일밤을 꼬박 세우며 작업하고 있는데, 잘 되지 않네요... ㅠ.ㅠ
    링크가 깨져 있어서요!!.. 소스를 전달해 주시면 감사 하겠습니다.
    소스 참조, 성능 개선 시켜 다시 전달해 드릴 것을 꼭 약속 드립니다.
    ican2727x@gmail.com

    perm. |  mod/del. |  reply.
    • 노헝그리 2009/07/15 14:28

      제가 블로그를 거의 관리 안하다보니-_-;

      어쨌든 소스 코드는 보내 드렸습니다~;

      뭐 매우 심플한 업데이터라 상용으로 쓰고자 하신다면~ 손을 많이

      보셔야 됩니다.

What's on your mind?

댓글 입력 폼
[로그인][오픈아이디란?]