728x90
간혹 CG 그림들을 바라 보고 있으면 한번쯤 그려보고 싶다는
생각이 자주 든다. 이정도의 수준은 아니더라도,
그 비슷한 정도의 화면정도를 바라고 있다.

그런 그림을 그리려면, 직접 손으로 그려야 하는데,
문제는 재료에 있다. 직접 그리려면, G펜과 잉크
그리고 채색을 위한 각종 붓과 도료 그 외에 파스텔 등이
필요해 진다. 게다가 각 색별로 구입을 하려면 엄청난 돈이
든다. 이런 저런 제약 조건에 실제적으로 손으로 그리는 것은
늘 한계가 따른다.

하지만, Tablet 이 있으면 다르다. 마우스 대신 펜으로 직접 그리고,
페인터 같은 프로그램을 쓰면 각종 화실 도구를 PC를 이용해
그대로 보면서 그려 나갈 수 있다.
파스텔이면 파스텔, 붓이면 붓,
에어브러쉬면 브러쉬 모든 기능을 PC 상에서 모니터로 바라보면서
직접 그려나갈 수 있다.
그런 작업을 하고 싶다.
게다가, 조그만한 타블렛이 아닌 A4 사이즈의 타블렛...

아... 가지고 싶다.
728x90
  1. 강정오 2003.11.19 04:07

    오 신혼살림에 푹 빠져 잇는 경환군~~
    요즘 므하고 사남???

  2. 김경환 2004.01.09 16:00

    나야.. 회사서 모니터 뚤어져라 보면서 살지^^
    다들 코딩쟁이라고들 부르는 일을 한다오..

728x90
유통기한이라고 하니... 무슨 음식같은 느낌이지만,
나의 품위 유지의 데드라인이라고 생각하면 된다.

진정한 폐인 꼬라지를 하게 되는 한계 시점이 바로 3일이다.
3일 동안 씻지 않으면 금새 폐인 꼬라지가 나기 시작하고,
냄새가 나기 시작한다.
그 덕에... 정말 우울해진다.
두뇌 활동은 정지하고, 만사가 귀찮아지면서,
움직임도 최소화 되고, 잠도 제멋대로 자게 된다.
식사도 물론 제멋대로 이지만..

이런 생활을 지금 5일째 진행중이다.
그래서 더더욱 머릿속을 엉켜 있고,
신체적인 발란스는 모조리 꼬여서 풀수 없는 상태가 되었다.
슬슬.. 더 엉키기 전에 서울에 올라가서 일단 씻고 봐야 겠다.

어디서든지, 최소한 근처에 베이스 기지가 있어야 한다.
씻고, 옷을 갈아 입을 수 있는... 그런 곳말이다.
728x90
728x90
정말 간만에... 통신을 하려고 MSN 설치하고,
로그인 하려는데, 이게 웬걸, 공사중이라고 나중에, 접속하란다.
참으로 화나게 만드는 환경이라지 않을까 싶다.

아주 간만에 접속좀 해보려는데, 이런데서 태클을 걸면,
조금은 슬픈 생각도 든다.
뭐, 그덕에 홈페이지에 다시 들를 수 있는 여유를 얻을 수 있긴하지만,
그래도 딱 뿌러지게 착착 돌아가지 않으면 무언가 놓쳐서
아깝다는 느낌이 드는건 어쩔 수 없나 보다.

처음에 MSN이 너무 오래된 버젼이라서 그런 문제인 줄 알아서
기존 버젼을 지우고 새버젼까지 엎어썼다.
그런 생쑈후에.... 메시지를 다시 확인했고,
MSN 유저 관리가 정리중에 있으므로, 현재 접속이 안될 수 도 있다는
메시지가 떴다. 칫...

728x90
  1. Favicon of http://www.hind.pe.kr 김형진 2003.11.10 11:08

    생각보다 읽기가 힘든 글이였다는. 무언가 열심히 생각하고 짱돌을 돌렸다는 느낌이지만.
    그렇다고 따르기엔 부담되는 글이라 생각되,.

728x90
앞서 언급한 "소설쓰기" 에서의 나의 글쓰기 습관 중 나쁘게 작동하는
원인은 물론 정리 안된 생각이 그 발단이지만,
어떻게 보면, 자꾸 스스로 잊어 먹어 버리는 문제로 인해 발생되는
문제이기도 하다.
한참을 이야기하다가 또는 한참을 글을 쓰다가 방향을 잊어 먹는다.
그래서 임기 응변으로 어떻게 돌리기도 하지만, 한계가 있는 법이다.
물론 이렇게 자꾸 잊어 먹는 것도 생각이 정리가 안되서 발생되는
문제점이겠지만...

잊어 버리기 전에 어떻게든 남기려는 나쁜 습관 덕에 글이
희안한 방향으로 종종 넘어간다. 즉 갑자기 다른 이야기가 펼쳐지는 흐름이 발생하는 경우를 의미하는데, 이는 무언가를 이야기하다 꼭 뒤에서 언급하려고 한 내용을 잊어 먹지 않기 위해서 급히 이야기를 접고 내가 잊어 버릴 뻔한 내용을 언급한다. 그러나 순서가 맞지 않는 내용이다.
이렇게 해서 나쁜 글을 또 다시 만들기 시작한다.
그렇게 어지럽히다가 보면, 어느 순간에서 부터는 더이상 손을 댈 수 없을 만큼 혼잡 난잡한 글이 되어 있어 내비두고 만다.

여유가 없어서 일지도 모르겠지만.... 이젠 그런 나쁜 글 습관을 어떻게든
막아야 겠다.
728x90
728x90
요즘 계속 프로그래밍만 손을 잡고 있어
이렇다할 글을 쓸 기회가 없다. 고작 쓰는 글이라고는
이 일기가 고작이다.
그러면서 느끼는 것은 점점 떨어져 가는 글쓰는 사고라고
생각된다. 무엇이 시작이고 무엇이 끝인지를 알 수 없는 글만
여전히 나열하고 있다. 그 덕에 느는 것은 어지럽게 나열된 글이다.

즉 자신의 생각이 정리가 되었다면 글의 시작과 끝이 명확할텐데,
늘 생각의 정리가 되어 있지 않으니 그 출발과 도착점이 늘 이상한곳에
존재하는 것이다.

만화중에 "오오 나의 여신님" 이라는 만화가 있다 .이 만화에서
주인공의 언니인 울드라는 여신이 있는데, 그녀의 최대 최악의 단점은
수단이 목적이 되는 것이다. 무엇가를 하기 위한 수단이 어느 순간부터
목적으로 변해 그것을 완료하고 난뒤 모든 일이 완료된 것처럼 군다.
단지 수단에 불과한 일인데 말이다.
만화로 볼때는 이 어이없는 행동이 늘 재미있는데, 막상 내 앞에
닥치니 이거 정말 아찔한 노릇이다.

내 글과 내 생각이 점점 그런 꼴을 거듭하는 것 같다.
무언가 목적을 가지고 글을 쓰기 위해 그 목적을 위한 수단의 글이
다시 목적으로 변해 완료 하고 난뒤 바라 보면... 정말 어이 없어진다.

하지만, 아직은 위안 삼아 생각하는 것은
반복적으로 단순 노동 처럼 계속 써 내려가면 이런 문제는 사라질 것이라는 것이다.

생각을 정리하기. 이를 중요하게 여기면서 글을 써나가야 겠다.
728x90
  1. Favicon of http://www.hind.pe.kr 김형진 2003.10.01 12:32

    어서 오련.
    얼마든지 환영.. ^^;
    그리고 이놈의 홈피 생긴지 꽤 됐어 ㅋㅋ

728x90
ActiveX 등록하기...


1. 우선은 *.cab 나 *.ocx 파일이 있어야 합니다.
  (앞으로 *는 test로 하겠습니다. - 제가 test로 시험을 해서...)
  cab나 ocx는 vb를 통해 만드는 방법이 많이 있으므로 생략하겠습니다.


2. test.lpk 화일 만들기
  lpk 파일을 만들기 위해서는 lpktool.exe 란 프로그램이 필요합니다.
  (마이크로소프트 사이트나 기타 사이트에 많이 있습니다.)
 
  압축을 푼 후 lpk_tool.exe 파일을 실행시키면 리스트 박스가 두개 나타나죠?
  왼쪽의 리스트 박스는 레지스트리에 등록된 목록입니다.
  등록명은 프로젝트명.클래스명 으로 나와 있습니다.
  (저의 경우는 test.usercontrol1으로 나와있더군요)

  만약 레지스트리에 등록이 않되어있다면 regsvr32 명령으로 먼저 등록하시구요..

  (다른곳은 test.lpk파일을 나중에 만들던데, 나중에 만들면 이상이 생기더군요..
     다음에 htm파일에 param테그를 고치는 부분이 있는데, 이것을 하려면 보안 인증 전에 먼저 lpk파일을 작성해야 합니다.)

  그리고 만들어진 test.lpk 파일을 가지고 이미 만들어진(vb로 만드셨다면 test.cab파일과 test.htm파일이 만들어지죠?) test.htm파일의 param테그 부분을 고칩니다.

  원본         : <PARAM NAME="LPKPath" VALUE="LPKfilename.LPK">
  고치고 난 후 : <PARAM NAME="c:test" VALUE="test.LPK">

  lpkpath부분은 lpk파일이 들어있는 곳의 풀패스를 적어야 합니다.


3. 이제는 그 문제가 많던 보안 부분의 해결입니다.
   (참고로 저는 델파이 사이트에서 어느분이 해결한 부분을 제가 다시 적용해서 적습니다.)

  마이크로소프트 사이트나 기타 사이트에 codesign.exe파일이나 inetsdk.exe파일이 있습니다. 두 파일은 모두 똑 같으므로 둘 중 하나만 받아서 사용하세요..

  압축을 풀고 다음과 같이 실행합니다.(명령프롬프트에서 하시는게 젤 편해요..)
  (앞으로 나올 *.pvk, *.cer, *.spc파일의 이름은 아무렇게나 해도 상관이 없고, 확장자만 잘 지키세요)

  ㄱ. 먼저 해당 디렉토리로 갑니다.(inetsdkbin까지)
  ㄴ. SETREG 1 True
  ㄷ. MAKECERT -n "CN=금명식의 보증서" -sv Test.Pvk Test.Cer
           - "cn="금명식의 보증서"부분은 아무 말이나 상관 없어요..
  ㄹ. [Create Private Key Password] 대화상자가 뜨며 암호를 요구하면 아무 거나 입력한다. 단 기억할 수 있는 암호로... (암호를 두번 물어보는데 - 기억으로는 sub암호까지 - 모두 같은 암호를 입력한다.)
  ㅁ. CERT2SPC Test.cer Test.spc
  ㅂ. 다시 대화상자가 뜨며 암호를 요구하면 아까 암호를 넣는다.
      (저의 경우는 한번도 안물어 보네요..)
  ㅅ. SIGNCODE -spc Test.spc -v Test.Pvk -n "Test" c:testTest.cab ( 여기서 Test.OCX는 내가 만든 OCX의 이름으로 대체하면 된다. 이름을 대체할때 파일이 저장된 풀 패스를 쓰세요)
  ㅇ. 또 대화상자가 뜨며 암호를 물어보면 아까 그 암호를 또 넣는다.
      (이것도 안물어 보는 경우가 있다는 사실...)


  위와 같이 해서 모두 성공하셨다면
  (참고로 ㄴ, ㄷ(ㄹ),ㅁ(ㅂ) 을 하게 되면 모두 succeeded란 메세지가 뜨고, ㅅ을 성공하게 되면

   warning : this file is signed, but not timestamped.
   succeeded
  란 말이 나오게 되는데 별 문제 없는것 같더라구요..)


4. 이제 체크를 해 볼까요?

  아직 명령프롬프트를 종료 안했죠?
  그 상태에서
   chktrust test.cab
  를 합니다. 그러면 어떤 메세지 박스가 뜨죠?
  그게 웹에서 다운 받기 전의 박스입니다.

  그러면 이제 모두 성공했어요..(참고로 전 3번의 방법으로 모두 test.ocx파일까지 했습니다.-다른 분이 "ㅅ"부분만 다시 하면 됀다고 하는데, 불안해서시리.. )


5. 이제는 탐색기에서 inetsdkbin폴더를 보시면 test.cer이란 파일이 만들어져 있죠..
 
  test.cer이란 파일을 실행시키면 보안 인증서를 얻을 수있습니다.
  다른건 다 참고로 보는 것이고 "일반탭에서-보증서설치버튼"을 누르세요..
  그리고  계속 "다음-다음-마침.."
  그럼 보증이 되었데요..



  이제 server가 된 컴퓨터에서는 레지스트리에 등록이 되어있어 시험은 못하고, 다른 컴퓨터로 이 곳으로 연동한다면 원하는 결과를 볼 수있을꺼에요..









***** asp와 vb연동하기 (param테그로 값을 vb로 넘기기) *****

1. ActiveX 컨트롤에 값을 받을 수 있는 프로퍼티를 만들어야 합니다.
방법은 비주얼베이직의 ActiveX컨트롤 인터페이스 마법사를 사용하면 간단
ActiveX컨트롤 인터페이스 마법사를 사용하는 방법
(1) 추가기능에서 추가기능관리자에서 ActiveX컨트롤 인터페이스 마법사를
추가하고 로드시킨다.
그러면 추가기능메뉴에 ActiveX컨트롤 인터페이스 마법사가 등록된다.
(2) ActiveX컨트롤 인터페이스 마법사를 실행
(3) 인터페이스 구성원 선택에서 불필요한 구성원은 모두 선택해제 한다.
필요하면 선택
(저는 모두 필요가 없어서 선택 해제했음)
(4) 사용자정의 구성원에서 추기를 클릭한다.
그리고, 예를 들어 memid라는 속성(프로퍼티)를 추가한다. 그리고, 다음
(여기서 추가를 할때 이름이 중요 - asp에서 그대로 이름을 사용한다.)
(5) 매핑설정은 필요하면 매핑시키고, 필요없으면 건너뛴다.
여기서는 건너뛰었다.
(매핑 설정을 했어요..
제가 한 것은 string형 변수가 필요했기 때문에, text박스를 하나 만들어서 그 박스의 text속성(text1.text)에다가 연결시켰어용)
(6) 특성설정인데 데이터형식을 지정한다.
여기서는 String을 지정하였다. 기본값은 "" 빈문자열로 하고
(7) 그리고 마침하면 아래쪽과 같은 코드가 생긴다.
이 코드는 memid라는 속성에 대한 ActiveX 컨트롤 인터페이스이다.


2. 비주얼 인터데브로 ASP페이지를 오픈하고
개발한 ActiveX컨트롤을 등록하고 페이지에 올려놓으면
화면에 ActiveX컨트롤이 보일 것임
(레지스트리에 등록되어 있으면(안돼면 regsvr32명령으로 등록을 먼저하자) 왼쪽 Toolbox에서 오른 마우스를 누른 후 내가 만든 ocx를 등록할 수 있다.)

3. 이 ActiveX컨트롤을 선택하고 등록정보를 보면 사용자가 작성한
프로퍼티를 확인할 수 있을 것임.
이 프로퍼티에 <  %=변수명%  > 이런 식으로 하고 웹페이지를
실행하면 값을 받을 것임.
(여기서 문제가 생기는 데, 인터데브는 .ocx파일만 전송하도록 되어있기 때문에 .cab파일도 전송하도록 해야 한다.
그러므로 .cab파일을 만들때 생기는 .htm파일을 보면 classID가 나온 후 "codeBase=test.CAB#version=1,0,0,0" 부분이 있다.
이걸 인터데브로 만든 파일의 classID이후 부분(.htm과 같은 위치)에 복사해서 붙여 놓는다.)


4. 그리고 값을 받은 뒤 바로 시행하게 하기 위해서는
UserControl_Show()이벤트에 해당코드를 작성하기 바람.
(UserControl_Show()안에서 text1.text의 값은 어느 변수에 기억 시키고 그 변수를 가지고 작업을 하게 되면 원하는 결과를 얻을 수 있다.
간단히 msgbox로 확인을 해 보면 쉽게 제대로 작동함을 알 수 있다.)
728x90
728x90
안녕하십니까?

에휴 어저께 친구 어머님이 돌아가셔서 밤을 샜더니 아직도
피곤이 남아있네요 ㅡ_ㅡ;

지난번의 이어서 계속 하겠습니다.

지난번에 초기화에 대해서 했는데, 이번에는 실제로 클라이언트에서
접속이 이루어졌을때 스레드를 생성하고 Accept 하는 과정까지 하겠습니다.
(생각같아서는 다 해버리고 싶은데 넘 양이 많고 힘들답니다 이해바람 ^^)

이번과정도 일반 소켓 프로그래밍 하실때 하는 알고리즘이기 때문에
아마 생소하지 않을 것입니다.

클라이언트로부터 접속 요청이 왔을때 스레드를 생성하고 새로운
통신용 소켓을 만드는 부분의 소스를 보시겠습니다.

// Listen.cpp : implementation file
//

#include "stdafx.h"
#include "ClientThread.h" // 이 헤더파일을 추가합니다.
#include "Listen.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CListen

CListen::CListen()
{
}

CListen::~CListen()
{
}


// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CListen, CAsyncSocket)
    //{{AFX_MSG_MAP(CListen)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif    // 0

/////////////////////////////////////////////////////////////////////////////
// CListen member functions

void CListen::OnAccept(int nErrorCode)
{
    // TODO: Add your specialized code here and/or call the base class
    CSocket sock;
    Accept(sock);
    CClientThread* pThread = (CClientThread*)AfxBeginThread(RUNTIME_CLASS(CClientThread),
THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED, NULL); // 스레드를 만들고 대기시킵니다.
    SOCKET socket = sock.Detach(); // 소켓핸들을 분리해서
    pThread->sSock = socket; // 생성된 스레드로 넘깁니다.
    pThread->ResumeThread(); // 스레드를 계속 돌립니다.
    CAsyncSocket::OnAccept(nErrorCode);
}

대충 보셔도 아시겠죠? ^^

접속 요청이 오면 우리가 만들어놓은 스레드 클래스를 이용해서 새로운 스레드를
만듭니다. 그후 Accept 된 소켓을 이 스레드에 접목시키면 되는것이죠
단. 주의하실 사항은 소켓은 생성된 스레드 이외의 다른 스레드에서 사용을 할수가
없답니다. 그래서 소켓 핸들을 분리해서(Detach) 사용하고자 하는 다른 스레드에서
연결(Attach)한후 사용할수 있답니다.

그럼 스레드에서 소켓 연결하는 부분을 보시겠습니다.

/////////////////////////////////////////////////////////////////////////////
// CClientThread thread

#include "Active.h"

class CClientThread : public CWinThread
{
    DECLARE_DYNCREATE(CClientThread)
protected:
    CClientThread();           // protected constructor used by dynamic creation

// Attributes
public:
    SOCKET sSock; // 받아올 소켓 핸들
    CActive sock; // 통신용 소켓 클래스
// Operations
public:

// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CClientThread)
    public:
    virtual BOOL InitInstance();
    virtual int ExitInstance();
    //}}AFX_VIRTUAL

// Implementation
protected:
    virtual ~CClientThread();

    // Generated message map functions
    //{{AFX_MSG(CClientThread)
        // NOTE - the ClassWizard will add and remove member functions here.
    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()
};

위의 소스는 스레드의 헤더 파일입니다.
Cpp 파일은 다음과 같습니다.

// ClientThread.cpp : implementation file
//

#include "stdafx.h"
#include "ClientThread.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CClientThread

IMPLEMENT_DYNCREATE(CClientThread, CWinThread)

CClientThread::CClientThread()
{
}

CClientThread::~CClientThread()
{
}

BOOL CClientThread::InitInstance() // 이부분은 아까 Accept 부분에서 ResumeThread()를 호출하면 발생합
니다.
{
    // TODO:  perform and per-thread initialization here
    sock.Attach(sSock); // 받아온 소켓 핸들을 CActive 클래스에 붙입니다.
    sock.m_pThread = this; // 소켓에서 자신의 스레드가 어떤것인지를 알려줍니다.

    return TRUE;
}

int CClientThread::ExitInstance()
{
    // TODO:  perform any per-thread cleanup here
    return CWinThread::ExitInstance();
}

BEGIN_MESSAGE_MAP(CClientThread, CWinThread)
    //{{AFX_MSG_MAP(CClientThread)
        // NOTE - the ClassWizard will add and remove mapping macros here.
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CClientThread message handlers

다음은 통신용 소켓(CActive)의 소스를 잠깐 보시죠 ^^

/////////////////////////////////////////////////////////////////////////////
// CActive command target

class CActive : public CSocket
{
// Attributes
public:

// Operations
public:
    CActive();
    virtual ~CActive();
public:
    CWinThread* m_pThread; // 자신의 소켓을 돌리고 있는 스레드 포인터

// Overrides
public:
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CActive)
    public:
    virtual void OnReceive(int nErrorCode);
    virtual void OnClose(int nErrorCode);
    //}}AFX_VIRTUAL

    // Generated message map functions
    //{{AFX_MSG(CActive)
        // NOTE - the ClassWizard will add and remove member functions here.
    //}}AFX_MSG

// Implementation
protected:
};

// Active.cpp : implementation file
//

#include "stdafx.h"
#include "ClientThread.h" // 이 헤더파일을 추가
#include "Active.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CActive

CActive::CActive()
{
}

CActive::~CActive()
{
}


// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CActive, CSocket)
    //{{AFX_MSG_MAP(CActive)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif    // 0

/////////////////////////////////////////////////////////////////////////////
// CActive member functions


void CActive::OnClose(int nErrorCode) // 접속이 종료될때
{
    // TODO: Add your specialized code here and/or call the base class
    Close(); // 종료하고 ㅡㅡ;
    m_pThread->PostThreadMessage(WM_QUIT, 0, 0); // 이 소켓을 돌리는 스레드도 종료합니다.
    m_pThread = NULL;
    CSocket::OnClose(nErrorCode);
}

소스가 한곳에 모여있는 게 아니라서 약간 헥갈릴수가 있으니 눈 크게 뜨시고
소스를 보세요 ^^

궁금하신 사항은 리플 달아주세요

p.s. 강좌는 계속 됩니다~ 쭈욱~


728x90
  1. 마훈 2003.03.24 13:28

    헐헐..파일 전송이 아니구 소켓..접속이자나여~

  2. Favicon of http://www.hind.pe.kr 김형진 2003.10.03 08:48

    흠.. 미처 몰랐는데... 그냥 데브피아서 긁어 온거라 ..^^:

  3. 김주원 2012.09.26 11:52

    컥 네이버 검색으로 소켓 검색하다가... 우연찮게 들렸는데... ㅋㅋ 형진씨네 방가~

    • Favicon of https://www.hind.pe.kr 하인도 2012.09.26 15:01 신고

      ㅋ 캄사 캄사~
      근데 이런 쓰레기 글이 네이X에 걸릴 줄은 몰랐는데요 ㅎㅎ
      지금 보니 좀 어이 없는 코드 ㅎㅎ

728x90
안녕하세요?

며칠의 시간이 흘렀네요...
이제 강좌를 시작합니다..^^

원래 계획대로라면 개발완료루 테스트 거쳐서 웬만한 버그 수정까지
다한후 할려고 했는데...시간이 넘 오래걸리는거 같아서
개발과 같이 강좌할려고 합니다 ^^

내용중에 잘못된 사항이 있을 수 있음을 미리 알려드리며 ㅡ_ㅡ;
잘못된 내용이 있다면 지적해주시기 바랍니다.

우선 오늘은 처음 초기화부분에
대해서 강좌 하겠습니다.

음 본론으로 들어가서...

파일 송수신에 대해서 간단하게 정리를 하자면 다음과 같습니다.

보내는 쪽--------------------
파일 오픈 - 파일정보 전송 - 일정단위의 패킷을 계속 읽어서 전송 - 파일 닫음

받는 쪽 --------------------
파일 오픈 - 파일정보 수신 - 일정단위 패킷을 계속 Write - 파일 닫음

간단하죠?
흑 사실 말이야 간단하지 막상하다보면 짜증난답니다 ㅡㅡ;

또한 가장중요한 것은 파일 송신하고 수신하는 부분은 어플과 같은 스레드에 두어서는
안된다는 것입니다. 그렇게 되면 파일전송하는 동안 마치 어플이 다운된거 처럼
보이게 되죠...아무런 이벤트도 먹질 않죠...이벤트가 안먹는다는것은?
전송도중 취소를 할수 없다는 뜻이죠 ㅡㅡ;

자 그럼 프로젝트를 시작해봅시다.

먼저 Visual C++을 띄우고..........................

Project에서 MFC AppWizard (dll) 을 선택한후 프로젝트 이름을 입력하고 다음...
확장DLL 로 할것이므로...MFC Extension DLL (using shared MFC DLL) 이것을 선택합니다.
Windows Socket도 체크를 해야겠죠...

Finish 버튼을 눌러 완료합니다.

App 클래스 딸랑 하나있죠?

이제 본격적으로 클래스를 추가해서 작업을 해야합니다.

자...CTransfer 라는 이름의 Generic 클래스를 하나 만듭시다.
상속 클래스는 없습니다.

헤더파일을 보면

class CTransfer  
{
public:
    CTransfer();
    virtual ~CTransfer();
};

이렇게 나오죠?
확장 DLL의 이 클래스를 외부 App에서 이용하기 위해서는 약간의 수정을 해야합니다.

class AFX_EXT_CLASS CTransfer  
{
public:
    CTransfer();
    virtual ~CTransfer();
};

이렇게 고칩니다.

우리는 이제 앞으로 이 DLL 을 이용할때 단지 CTransfer 라는 클래스만 이용해서
파일전송을 하면 됩니다. 그렇다면 CTransfer 라는 클래스에 모든 기능을 다 집어넣어야겠죠..

이제 메인 클래스를 만들었으니, 관련된 소켓, 스레드 클래스를 한번 만들어보겠습니다.

CListen 이라는 이름의 CAsyncSocket 을 상속받아서 클래스를 만듭니다.
CActive 라는 이름의 CSocket 을 상속받아서 클래스를 만듭니다.
CClientThread 라는 이름의 CWinThread 를 상속받아서 클래스를 만듭니다.

CTransfer 클래스에서 소켓을 Listen 시키기 위해 관련된 함수를 추가합니다.
소스는 다음과 같습니다.

Transfer.h ----

#include "Listen.h"

class AFX_EXT_CLASS CTransfer  
{
public:
    CTransfer();
    virtual ~CTransfer();
public:
    CListen* m_pListen;
    void Listen();
};

Transfer.cpp ----

CTransfer::CTransfer()
{

}

CTransfer::~CTransfer()
{
    delete m_pListen;
    m_pListen = NULL;
}

void CTransfer::Listen()
{
    m_pListen = new CListen;
    m_pListen->Create(3500); // 포트번호는 임의로 결정하세요.
    m_pListen->Listen();
}

자 초기화 부분은 끝났습니다.

이어서 이어지는 강좌는 클라이언트가 접속할때 스레드를 생성하고 관리부분에 대해서
추가하겠습니다.
728x90

+ Recent posts

728x90