C:\unigine\externs\bin;C:\unigine\lib;C:\unigine\bin;C:\Python26;"C:\Program Files\Microsoft DirectX SDK (October 2006)\Utilities\Bin\x86";%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;c:\Program Files\Microsoft SQL Server\90\Tools\binn;C:\Program Files\Microsoft SQL Server\90\Tools\binn;C:\Program Files\TortoiseSVN\bin;C:\Program Files\Common Files\Compuware;C:\Program Files\Microsoft SQL Server\90\Tools\binn\;C:\Program Files\Unigine\Evaluation Kit\tools\x86

위에는 실제로 사용하는 나의 path 경로 였었음.
헌데 scons를 쓰려고 하닌까 자꾸만 타이틀의 오류가 나면서 안되길래 한참을 고민했는데,
결국 찾아낸 문제의 부분!! "C:\Program Files\Microsoft DirectX SDK (October 2006)\Utilities\Bin\x86";
dx가 두가지가 깔려있는데 2006 8월이랑 2009 3월버전. 물론 2006 8월은 쓰이질 않고 지우는걸 깜박해서 그냥 냅뒀었는데, 그게 문제가 될줄이야.
요기까지는 잡설이었고.

요점! path 잡을때 ( ) 가 들어가면 링크가 엉망이 됨....
젠장 (October 2006)...
예상되지 않았다는 오류가 난다면 자신의 컴퓨터 path가 제대로 되어있는지 확인을 해보자. 혹시 몰라 검색해보니, path가 안 잡혀 있는 상태로 뭔가를 하려 할때도 난다고 하는데 그 부분은 아직 헤딩해보질 못해서 잘 모르겠다.

내컴터 오른쪽클릭 - 시스템 등록 정보 - 고급 - 환경변수 - 시스템변수 - path에 가면 자신의 윈도우 path를 수정할 수 있다.
글타고 막 수정하진 말자. 언제나 백업을 위주로~!

포스팅 할 예정이 아니어서 인증샷찍는걸 깜박..;
[-] Collapse
#include <iostream>
#include <ctime>
#include <string>

#define _WIN32_WINNT 0x0501

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>

using boost::asio::ip::tcp;

std::string make_daytime_string()
{
    std::time_t now = std::time( 0 );
    return std::ctime( &now );
}

class Ctcp_connection : public boost::enable_shared_from_this< Ctcp_connection >
{
public:
    typedef boost::shared_ptr< Ctcp_connection > pointer;

    static pointer create( boost::asio::io_service &io )
    {
        return pointer( new Ctcp_connection( io ) );
    }

    tcp::socket &socket()
    {
        return m_socket;
    }

    void start()
    {
        m_message = make_daytime_string();
        // # handle_write 함수에서 매개변수 2가지를 사용할 필요가 없다. 함수 다이어트
//  boost::asio::async_write( m_socket, boost::asio::buffer( m_message ),
//  boost::bind( &Ctcp_connection::handle_write, shared_from_this(),
//  boost::asio::placeholders::error,
//  boost::asio::placeholders::bytes_transferred) );

        std::cout << "5-1 prepare async write" << std::endl;

        boost::asio::async_write( m_socket, boost::asio::buffer( m_message ),
            boost::bind( &Ctcp_connection::handle_write, shared_from_this() ) );

        std::cout << "5-2 send daytime to client and binding" << std::endl;
    }

private:
    Ctcp_connection( boost::asio::io_service &io )
        : m_socket( io )
    { }

// void handle_write( boost::asio::placeholders::error_code & /*error*/,
//  size_t /*bytes_transferred*/ )
// { }

    void handle_write()
    { }

    tcp::socket     m_socket;
    std::string     m_message;      // char[] or std::vector도 사용 가능
};

class Ctcp_server
{
public:
    Ctcp_server( boost::asio::io_service &io )
        : m_acceptor( io, tcp::endpoint( tcp::v4(), 13 ) )
    {
        std::cout << "1 call creater" << std::endl;
        start_accept();
    }

private:
    void start_accept()
    {
        std::cout << "2 call start accept func" << std::endl;

        Ctcp_connection::pointer new_connection = Ctcp_connection::create( m_acceptor.io_service() );

        std::cout << "3 prepare async" << std::endl;

        m_acceptor.async_accept( new_connection->socket(), boost::bind( &Ctcp_server::handle_accept,
            this, new_connection, boost::asio::placeholders::error ) );

        std::cout << "4 async complete and binding\n --Wait Connect" << std::endl;
    }

    void handle_accept( Ctcp_connection::pointer new_connection, const boost::system::error_code &error )
    {
        if( !error )
        {
            std::cout << "5 start handle_accept" << std::endl;
            new_connection->start();
            std::cout << "6 call start_accept func" << std::endl;
            start_accept();
        }
    }

    tcp::acceptor   m_acceptor;
};

int main()
{
    try
    {
        boost::asio::io_service io;
        Ctcp_server server( io );
        io.run();
    }
    catch( std::exception &e )
    {        std::cerr << e.what() << std::endl;
    }

    return 0;
}
출력된 결과


중간 --Wait Connect 라는 부분은 Client로 접속하기 전까지 대기 상태로 유지된다.
5번부터 4번까지( 5 -> 5-1 -> 5-2 -> 6 -> 2 -> 3 -> 4 ) Client 가 접속될때 실행되는 부분이다.

소스를 조금 분석하자면,
m_acceptor.async_accept( 소켓, bind( 연결할 함수 포인터 ) );
프로그램이 흐르다가 이 부분을 만나면 무작정 대기에 빠진다. 물론 async이기 때문에 다른 작업이 가능하다.
상단의 소스에는 thread를 쓰고 있지 않기에 무한대기 상태에 빠진것처럼 보인다.

다시 말하자면, 명시된 소켓으로 Client가 접속이 될때까지 binding된 콜백함수를 호출하지 않는 것이다.

클라이언가 접속이 되면( 즉, accept 가 되면) 바인딩된 함수로 호출이 되는것이다. 그 전까지는 함수를 호출하지 않는다. )

5-1과 5-2 사이에도 async_write 함수가 있는데 이것 역시 같은 맥락일 것이라 예상된다.이 부분은 나중에 thread를 추가 하고 나서 다시 한번 테스트. 하지만, asio의 흐름상 비슷할거라 생각된다. 명시된 소켓으로 패킷을 날리는데, 다 날라갈때까지 대기를 하고 다 날라간 이후엔 binding된 콜백함수를 호출한다.

소스에는 호출되는 콜백함수( Ctcp_connection::handle_write )는 내부가 비어 있기 때문에 아무 처리를 안 한다.
이론적으로 흐름을 잡자면, handle_write를 5-3이라 한다면, 5-1 -> 5-3 -> 5-2 이 될것이다.
만약 보낼 패킷의 양이 많아 async 상태가 된다면 5-1 -> 5-2 -> 처리가 끝날때 까지그외에 다른 부분 -> 5-3 이 될것이다.

하나의 Client가 접속을 하고 daytime을 받아간후 6번을 지나면 다시 2번으로 돌아간다.
여기서 다시 async_accept에서 대기.

요기까지 개인적으로 분석한 Asio Tutorial 중 Daytime.3 - An asynchronous TCP daytime server 부분이다.

post script.
cout으로 번호랑 주석 비스므리하게 출력한건 분석하기 위해 임의로 추가한 부분입니다.

'Programming > Boost' 카테고리의 다른 글

asio -- 1  (0) 2009.12.01
Bind 공부중인거 정리. < 01 >  (0) 2009.08.20
Signal 공부중인거 정리. < 04 >  (0) 2009.08.20
Signal 공부중인거 정리. < 03 >  (0) 2009.08.20
Signal 공부중인거 정리. < 02 > - 1  (0) 2009.08.19
asio -- 1 Programming/Boost 2009. 12. 1. 12:23
[-] Collapse
#define _WIN32_WINNT 0x0501

#include <iostream>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

int main()
{
    boost::asio::io_service io;
    boost::asio::deadline_timer t( io, boost::posix_time::seconds( 10 ) );

    std::cout << "test" << std::endl;

    t.wait();       // 10초 동안 대기. blocking

    std::cout << "ttttt" << std::endl;
}
블록모드. 10초동안 대기를 명하고, wait를 만나게 되면 10초동안 말 그대로 wait(대기) 한다. 만약 wait 명령어를 호출 해주지 않는다면, 그냥 패스~

'Programming > Boost' 카테고리의 다른 글

asio - TCP_server( async )  (0) 2009.12.01
Bind 공부중인거 정리. < 01 >  (0) 2009.08.20
Signal 공부중인거 정리. < 04 >  (0) 2009.08.20
Signal 공부중인거 정리. < 03 >  (0) 2009.08.20
Signal 공부중인거 정리. < 02 > - 1  (0) 2009.08.19
std::map< int, int > Map1;
이런녀석이 있다고 할때 Map1[1], Map1[2] 처럼 접근이 가능하다. 물론 리턴값은 first에 맞는 second

그런데 std::map< int, int > *pMap2;
이렇게 선언되어있는 녀석이 있다면 pMap2[1], pMap2[2] 의 접근이 불가능하다.
이유인 즉슨!!

일반 map 에서 정의되어 있는 [] 오퍼레이터가 제대로 작동하지 않아서이다.
포인터 map에서의 []는 int *pI = new int[10]; 에서의 pI[1] 와 같은 의미.

결국 map 이라는 녀석이 할당된 메모리 주소를 쭉 찾아가다보니 당연히 first 값을 넣어도 second가 나오지 않는다.

( 확실한건 아니고 나의 가설일뿐 ㅎㅎ )

그렇다면 포인터로 선언한 map은 쓸수 없는가?
당연히 사용이 가능하다. 세가지 방법중 맘에 드는걸로 쓰는걸 추천~

1. 레퍼런스를 만들어 참조한다.
std::map< int, int > &refMap = *pMap2;
- 장점은 일반 map 사용하듯이 쓰면 된다.
- 단점은 주소 복사연산이기 때문에 변수 생성시에만 가능하다.
std::map< int, int > &refMap; << 선언 에러
std::map< int, int > refMap;
&refMap = *pMap2; << 말도 안되는 연산. 당연히 에러

2. 주소를 열심히 찾아가는 방법을 쓴다.
int iSecond = (*pMap2)[0];
- 장점은 레퍼런스가 아니니 때문에 어디서든 map 포인터에서 second의 값을 불러올 수 있다.
- 단점은 아직 못 찾았는데, 개인적으로 미관상 소스가 이쁘지 않다! ㅋㅋㅋ

3. 이터레이터를 사용한다면 아무 문제없다.
포인터든 아니든 이터레이터는 진리.

post script.
map은 [] 오퍼레이터 내부에서 find 와 insert를 돌린다. find로 있으면 second리턴 없으면 insert
( 이걸 모른다면 map 공부를 다시 하시길.. ㅋ )
위에 쓴 예시는 내부에 값이 있다는 전제하에 쓴 글임니당.

vector나 list에서도 같은 문제가 발생하겠죵? 테스트를 안해봐서 이건 모릅니다! ㅋ
웹에서 글을 쓸때
& # 8238; (붙여서 쓰세요.) 을 제일 앞에 붙이면 입력한 한글 문자열이 뒤집혀 나온다능~ ㅋㅋㅋ

'잡동사니' 카테고리의 다른 글

무슨 게임 무슨 엔진  (0) 2010.01.10
성향 테스트  (0) 2009.10.05
UNICODE <-> UTF8  (0) 2009.08.17
#ifdef WIN32
#define TRACE(fmt, ... ) Func( fmt, __VA_ARGS__ )
#else
#define TRACE(fmt, args...) Func( fmt, ##args )
#endif