사실 이책을 4번은 봤겠지만 정식으로 재대로 본것은 약 세번째인것 같다..

사실 이렇게 짧은 시간에 한권을 봤다는것이 믿기지가 않는다..

6월 25일부터 불과 5일만에 다 봤다.

놀랍다.

전에 봤을때는 한 한달 이상은 걸린것 같은데 말이다.

아무튼 지금까지 ACE에 109시간을 투자했다.

그런데 문제가 발생했다.

지금까지는 하루 3~5시간중 2시간 이상은 책으로 채웠는데
이제 읽을책이 별로 없다.

이제 실습으로 3~5시간을 채워야하는데... 어떻게하지?

이제 The C++ Network Progrmming Volum2을 다시 읽어야할것 같지만..
이건 본지 별로 안되었다. 좀 흥미가 나지 않을것 같아 걱정이네^^

실습은 메신저 서버, 혹은 ACE 기초 클래스를 구현해 보는걸로 결정했다.

약간은 해맬걸 같지만 ^^ 그래도 10000시간을 해낼테다^^
이 책을 4번째 봤다.
첫번째는 그냥 어렵게 봤고 두, 세번째는 대충 본것 같다.

4번째는 ACE에 필요한 지식을 다시한번 다지기 위해 자세히 재밌게 봤는데.. 역시 좋은책이었다.

tcp/ip 기초 --> IO 멀티 플렉싱(select등) -->  동기화 예제(mutex, semaphore) --> 쓰레드 --> IOCP 순으로 가는
체계적으로 상위 수준으로 올라가는 방향이 참으로 좋았고

TIP/IP 프로그래밍에 필요한 mutex, semaphore, Event 등을 쉬운 예제로 설명해주는것
IOCP를 쓰기위해 사전에 필요한 지식들(쓰레드, 비동기 입출력,  Overlaleed 입출력)을 설명및 쉬운 예제로 보여주는것또한 좋았다.

초, 중급 네트워크 프로그래머에게 상당히 도움이 될 책인것은 분명하며
초급 프로그래머시면 한번만 읽지 마시고 시간을 충분히 가지고 충분한 시간이 지난다음 여러번 읽어보는것 또한 좋을것 같다.

다음은 다시 C++ Network Programming Vaolum 1 ACE와 패턴을 사용한 객체 지향 네트워크 프로그밍 책을 3번째 볼 생각이다.

현재 ACE에 90여시간 투자중이다.^^ 앞으로의 계획은 ACE(ACE와 ACE를 배우는데 필요한 지식들)에 1만시간을 투자하는것이다.

ACE_wrappers/examples/NT_Service 에 있는 서비스 등록을 참고(배껴서? ㅡ.ㅡ)하여 서버 프로그램을
서비스화 하였다.

그런데 서비스 등록후 시작하지 않는 문제가 발생했습니다.

이상한건 특정 사용자로 로그온하여 실행하면 된다는것입니다.


알고 보니 파일에 권한에 SYSTEM 없었습니다.^^
그래서 SYSTEM 권한을 추가하였습니다.

그런데. 그런데로 안되었습니다 ㅡ.ㅡ
또 알고 보니 실행파일이 있는 곳에 로그 파일을 만드는데.. 로그 파일을 못만들어서 생기는 문제가 있더군요.
해당 디렉토리를 작업 디렉토리로 설정하는것을 까먹었더군요^^


        // 작업 디렉토리 설정.
        char    workdir[128];
        GetModuleFileName( 0, workdir, sizeof workdir  );

        char *    pDir = ::strrchr( workdir, '\\' );
        if( 0  != pDir )
            *pDir = 0;

        ::SetCurrentDirectory( workdir );
마지막으로 해당 디렉토리에 SYSTEM 권한을 주어 해결하였습니다.


ACE_Reactor보다 ACE_Proactor 개념이 더 어려운걸로 알고 있고 그랬지만..

이상하게 구현하는것은  ACE_Proactor가 훨씬(한 4배) 적용하기 쉽게 느껴진다.

지금까지 Reactor에 목을 맨 나로로는 허망하다 ㅎㅎ

아무튼 최근까지 ACE에 51시간 투자했다.

1차 목표는 8월 31일까지 ACE에 300시간 투자^^
2차 목표는 2011년 5월 31일까지 ACE에 1000시간 투자 목표
최종 목표는 2020년 5월 31일까지 ACE에 1만시간 투자 목표

ACE의 ace가 되는 날까지 보고 해보고 보고 해보고 보고 해보고~~
ACE_Select_Reacot를 ACE_Reactor::instance 에 적용예제
윈도우에서 ACE책 예제(ACE 프로그래머 가이드, C++ NetworkProgramming Volum1, 2)에 나온 소스를 볼때 Select_Reactor로 적용하는것이 작동을 원할하게 할수 있다.


#include "ace/Select_Reactor.h"
#include "ace/Reactor.h"

int ACE_TMAIN( int , ACE_TCHAR * [] )
{
    ACE_Select_Reactor * ps = new ACE_Select_Reactor;

    // 두번째 인자를 true로 하면 Reactor가 삭제될때 첫번째 인자로 넘긴 Reactor를 자동삭제 된다.
    ACE_Reactor * pr = new ACE_Reactor( ps, true );

    // 두번째 인자를 true로 하면 Reactor가 삭제될때 첫번째 인자로 넘긴 Reactor를 자동삭제 된다.
    ACE_Reactor::instance( pr, true );
    ...
    ...

    ACE_Reactor::instance()->run_reactor_event_loop();

    return 0;
}
링크 에러

LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library

해결책
환경 설정  --> Linker --> Input -->Ignore Specific Library

msvcrt.lib

입력 후 리빌드.

Tip : 링커 command line 에 /VERBOSE:LIB 를 추가하면 링커가 검색중인 라이브러리가 보인다.

아래 처럼 Visual Studio 2008 에서

솔류션 탐색기에 현재 편집중인 파일위치를 알수 있게 해준다.

지인 사이트 KeyTol 블로그 에서 발췌하였다^^




옵션은 아래를 참고^^


[하프]초미지향 님 Mabinogi Server CheckUp 1.2 소스 참고 했습니다.

한국 본서버 기준 :
http://211.218.233.238/patch/patch.txt

파일 중에
patch_accept 값이 1 이면 게임 접속이 가능하다

patch_accept=1

테스트 서버 URL
http://211.218.233.238/patch/patch_test.txt



C/C++로 구현한다면

Socket으로 211.218.233.238 80번 포트로 연결후
"GET /patch/patch.txt HTTP/1.0\r\n\r\n" 을 보내고(send)
결과값을 받는다 (recv)


Task 구현
class LogTest_Task : public ACE_Task<ACE_NULL_SYNCH>
{
	typedef ACE_Task<ACE_NULL_SYNCH>	super;
private:
	ACE_Log_Msg_Callback * m_pLogCallback;

public:
	LogTest_Task( ACE_Log_Msg_Callback * logCallback )	:
		super(),
		m_pLogCallback( logCallback )
	{
	}

	virtual int		svc()
	{
		if( m_pLogCallback )
		{
			ACE_LOG_MSG->set_flags( ACE_Log_Msg::MSG_CALLBACK );
			ACE_LOG_MSG->clr_flags( ACE_Log_Msg::STDERR );
			ACE_LOG_MSG->msg_callback( m_pLogCallback );
		}

		// Log 출력.
		ACE_DEBUG( ( LM_DEBUG,
					ACE_TEXT("DEBUG hello World") ) );
		ACE_ERROR( ( LM_ERROR,
					ACE_TEXT("ERROR hello World") ) );	
		return 0;

	}

};


호출
// Task생성및 Task 실행.
LogTest_Task	logTask( ACE_Log_Msg::instance()->msg_callback() );
logTask.activate();
logTask.wait();
추가된소스
BOOL CACE_MFCApp::InitInstance()
{
        .....

        /////////////////////////////////////////////////////////////////
        // 추가
        WORD                    wVersionRequested;
        WSADATA                 wsaData;
        int             err = 0;

        wVersionRequested = MAKEWORD( 2, 2 );
        if( WSAStartup( wVersionRequested, &wsaData ) != 0 )
                return FALSE;

        ACE::init();
        /////////////////////////////////////////////////////////////////

        CACE_MFCDlg dlg;
        m_pMainWnd = &dlg;
        INT_PTR nResponse = dlg.DoModal();
        if (nResponse == IDOK)
        {
                // TODO: Place code here to handle when the dialog is
                //  dismissed with OK
        }
        else if (nResponse == IDCANCEL)
        {
                // TODO: Place code here to handle when the dialog is
                //  dismissed with Cancel
        }

        /////////////////////////////////////////////////////////////////
        // 추가
        ACE::fini();
        WSACleanup( );
        /////////////////////////////////////////////////////////////////

        // Since the dialog has been closed, return FALSE so that we exit the
        //  application, rather than start the application's message pump.
        return FALSE;
}

+ Recent posts