한빛미디어에서 e-book으로 'Boost.Asio를 이용한 네트워크 프로그래밍' 이라는 책이 막 출간 되었습니다.

http://www.hanb.co.kr/ebook/look.html?isbn=9788968486111

 

제가 집필한 책으로 Boost 라이브러리 중의 하나인 Asio를 사용하여 네트워크 프로그래밍 하는 방법을 알려주는 책입니다.

 

책의 난이도는 네트워크 프로그래밍 기준으로 초급서입니다. C++은 알고 있지만 네트워크 프로그래밍에 관한 지식이나 경험이 거의 없는 분들을 대상으로 하였습니다(예를 들어 socket 프로그래밍 간단한 예제 하나 정도 본 경험이 있는 분들).

 

네트워크 프로그래밍에 경험이 있으시거나 Asio를 이미 사용해본 분들은 이 책을 보면 별로 흥미로운 것이 없을 수 있습니다. e-book의 한정된 지면에 초급에서 고급까지 모든 것을 담기 힘들고, 고급 내용은 사실 Asio의 대한 것 보다는 병렬 프로그래밍이나 게임 서버 구축에 대한 것으로 이것은 Asio를 벗어나는 것이라고 생각했습니다.

 

다만 e-book 이라는 특징을 잘 살릴 수도 있습니다. 출판사의 협조만 있다면 책이 출간된 이후라도 주기적으로 새로운 내용을 추가해 나갈 계획을 가지고 있습니다. 이러기 위해서는 책이 어느 정도 판매 되어야 하고, 독자 분들의 피드백이 있어야겠죠^^;

 

개인적으로 이후 추가 하고 싶은 것은

Asio 샘플 중 흥미로운 것 분석

linux에서 Asio를 사용한 프로그래밍

Asio를 사용한 네트워크 라이브러리 만들기

간단한 온라인 보드 게임 만들기

웹 상에서 얻은 Asio 기술 정리

등등 입니다.

 

 

네트워크 프로그래밍은 잘 모르지만 멀티플랫폼, 비동기 네트워크, 또는 범용적인 비동기 프로그래밍을 하고 싶은 분들에게 이 책이 도움이 되기 바랍니다^^

 

 

by 흥배 2013. 6. 5. 08:00
  • Prographer J 2013.07.10 01:42 신고 ADDR EDIT/DEL REPLY

    안녕하세요 이북구매하고 예제 따라해보다가 의문점이 있어서 글 남겨요 ^^;
    async에서 session 클래스 있잖아요? session을 session.h / session.cpp로 나눠서 작업을 하면

    오류 1 error C2248: 'boost::asio::basic_io_object<IoObjectService>::basic_io_object' : private 멤버('boost::asio::basic_io_object<IoObjectService>' 클래스에서 선언)에 액세스할 수 없습니다.

    이런 오류가 발생하더라고요...하지만 한 파일(session.h)에 다 넣으면 문제 없이 잘 동작하고요..
    이거 왜 이럴까요?? 무조건 한파일에서 작업해야 하나요? 그렇다면 예제처럼 한파일에 main까지 다 있어야 하는데...뭔가 제가 잘 못 한거 같은데 뭔지 모르겠어요 ㅠㅠㅠ

    구글링해도 답이 안나오고 예제는 다 파일 하나로 되어 있고요..
    답답해서 올립니다..

    감사합니다.

    • 흥배 2013.07.10 08:44 신고 EDIT/DEL

      Asio의 문제는 아니고 한상자님이 만든 클래스의 접근 수준이 잘못되서 발생한 것 같습니다. 책의 예제는 최대한 간단하게 하기 위해서 하나의 파일로 만들었지만 보통은 .h와 .cpp 파일 분리를 합니다(덩치가 크다면). 책의 예제 중 ChattingTCPServer의 경우 ServerSession 클래스가 .h와 .cpp가 나누어져 있습니다.

    • Prographer J 2013.07.10 20:44 신고 EDIT/DEL

      안녕하세요!
      댓글 감사합니다.
      boost::asio::ip::tcp::socket& Socket() 할 때 &<-- 요거 빼먹어서 그렇네요 ㅠㅠ
      그런데 어제 할 때 넣어서 한거 같은데.. 집에가서 다시 한번 테스트 해봐야겠네요..ㅠㅠ

      그런데 socket을 갖고 올때 &를 붙이고 안붙이고 차이가 왜 나는건가요? 안 붙이면 액세스 에러나고 붙이면 액세스 에러가 안나네요..

      감사합니다.

  • Prographer J 2013.07.19 00:10 신고 ADDR EDIT/DEL REPLY

    안녕하세요 책 잘 보고 있습니다. 책을 보다보니 코드가 이상한 부분이 있는것 같아서 질문 남깁니다.
    p69 마지막에
    // 큐에 저장된 데이터가 있다면 데이터를 보낸다.
    if( m_SendDataQueue.empty() == false )
    {
    m_bCompletedWrite = false;
    char* pData = m_SendDataQueue.front(); <-------------------pop을 하지 않고,
    PACKET_HEADER* pHeader = (PACKET_HEADER*)pData;
    PostSend( pHeader->nSize, pData ); <------------------------이부분을 호출하게 되면
    }


    void Session::PostSend( const int nSize, char* pData )
    {
    m_SendDataQueue.push_back( pSendData ); // 보낼 데이터를 큐에 저장
    if( m_bCompletedWrite == false )
    {
    return;
    }
    .....
    }

    m_SendDataQueue.push_back( pSendData ); // 보낼 데이터를 큐에 저장 <---여기에서 queue에만 계속 쌓이지 않나요??
    그렇게되면 무한루프가 돌거 같은데요..

    감사합니다.

    • 흥배 2013.07.19 08:27 신고 EDIT/DEL

      며칠전에 관련 코드 버그를 발견해서 수정을 했습니다^^;;;;;
      지금 책에 적용된지 모르겠는데 http://dev.naver.com/scm/viewvc.php/trunk/Boost_Asio/?root=sampletutorial 여기에 가면 소스 코드가 있으니 일단 소스 코드를 먼저 봐 주세요

  • Prographer J 2013.07.19 11:32 신고 ADDR EDIT/DEL REPLY

    안녕하세요.. 제가 말씀 드린 부분은 부등호 부분이 아니라
    PostSend할때요 handle_write 이 부분에서 m_SendDataQueue.empty() == false(63라인)면 m_bCompletedWrite = false; 설정 하고,
    char* pData = m_SendDataQueue.front();(67라인) 이렇게 첫 데이터를 갖고 와서 다시
    PostSend( pHeader->nSize, pData );(71라인) 이쪽으로 넣잖아요?
    그렇게 되면 PostSend함수에서
    m_SendDataQueue.push_back( pSendData );(44라인)이 실행되면서 제일 앞에 있던 Data가 다시 뒤에도 저장되지 안나해서요...
    68라인쯤에 m_SendDataQueue.pop_front(); 이 부분을 넣던지,
    71라인의 PostSend부분을 boost::asio::async_write~~~~~ 이 함수로 대체해야 되지 않나 라는 생각이 들어서요 ^^;;

    감사합니다.

    • 흥배 2013.07.19 14:19 신고 EDIT/DEL

      그래서 PostSend가
      void PostSend( const bool bImmediately, const int nSize, char* pData ); 이렇게 바뀌었습니다

  • Prographer J 2013.07.19 18:15 신고 ADDR EDIT/DEL REPLY

    음.. 적용이 안된건가요?? svn으로 받은 코드는 기존 코드 그대로 인데요;;; ServerSession.cpp맞죠? 39라인...

    • 흥배 2013.07.19 20:43 신고 EDIT/DEL

      제가 서버쪽 수정을 빼 먹었네요^^;;; 좀 더 자세히 확인 해야 하는데 그렇지 못해서 죄송합니다^^;;;

  • Pururoong 2013.07.22 23:56 신고 ADDR EDIT/DEL REPLY

    비동기 채팅 서버 예제 때문에 질문 드립니다.
    클라이언트가 접속할 때 마다 세션이 nMaxSessionCount가 증가하는데로 만들어지는데, 중간에 세션이 종료되면 다음에 접속하는 클라이언트가 그 부분에 들어가야 하는거 아닌가요?

    • 흥배 2013.07.23 08:49 신고 EDIT/DEL

      nMaxSessionCount는 최대 사용할 클라이언트 객체 수로 클라이언트가 접속이 종료되면 m_SessionQueue로 종료된 Session 객체의 인덱스가 추가되어 다음에도 사용할 수 있게 됩니다. 그리고 해당 Session 객체의 초기화는 처음 사용할 때 초기화 합니다.

    • Pururoong 2013.07.23 16:37 신고 EDIT/DEL

      답변 감사드립니다.

      방금 MAX_SESSION_COUNT 3으로 넣고 돌려봤는데요
      접속을 3번 받으니까 그냥 종료되더라구요..
      아마 접속끊을 때 소켓 닫는 부분이 없어서 그런 것 같다는 생각이 듭니다.

      ChattingServer.h에
      void CloseSession( const int nSessionID )에서 큐를 pushback한 다음에
      m_SessionList[nSessionID]->Socket().close(); 이라고 추가해줬는데,
      잘 돌아가는 것 같습니다. 제가 맞게 하고 있는건지 확인 부탁드릴게요.
      감사합니다.