네트워크라는 개념이 생성되면서, 여러가지 계층간 통신이 생겨났다.
일반적으로 어플리케이션 개발자들이 사용하는 통신은 최상위 계층을 다루게 되며..
주로 소켓통신, 혹은 파이프와 같은 것을 이용하여 로컬 프로세스간 혹은 원격지 프로세스간에
통신을 하게된다.

여기서는 메시지를 주고받은 통신에서, 데이터를 공유하는 것을 통털어... 알고 있는것만 정리한다. -0-;;;
모르는 것을 어떻게 하나 ^^;;; (누가좀..)

이 계통에 들어선지 시간이 좀 흘럿지만, 참으로 다양한 방식이 존재하고..
공부해야할 것도 너무 많다.. -0-;;;

1. SOCKET - 통신
   통신 프로그램을 짜면 가장 먼저 접하는 것이 소켓이다. 하위호환 덕택에 아직도 명맥을 유지하는 BSD 모델과
   winsock으로 불리우는 2가지 모델을 윈도우에서 제공해준다.
   서버/클라이언트 모델로 제공되며, TCP/UDP 이렇게 상위 2가지를 주로 사용한다.
   (이건 머, 어떻게 심플하게 설명할 방법이 없다... 책사서 봐야지 ㅋ~)

2. ATOM - 공유
   시스템에서 제공하는 테이블을 이용하여, 문자열 데이터를 공유할 수 있도록 제공해준다.
   ATOM 이라고 불리우는 2바이트 숫자를 키 값으로 이용하여 255바이트까지의 문자열을 해당 시스템의 테이블에
   저장하고, 가져다 쓸 수 있다.  사용방법이 너무 간단하고, 윈도우 95까지도 지원한다.
   함수도 아래의 6개가 다이고, 그나마 로컬과 글로벌을 구분하기 위한 정도뿐이다. 

   9번 DDE 섹션을 보면, ATOM과 SendMessage 를 이용하여, 어떻게 데이터 통신을 할 수 있는지
   다양함 샘플을 보여준다. 

ATOM Overview


 
3. PIPE - 통신
   로컬머신, 혹은 로컬 네트웍 그룹내에서 사용이 가능한 통신 방식이다. 소켓보다 조금 들 복잡하지만 소켓처럼
   정밀하게 제어하기는 조금 쉽지 않다.
   이름 있는 파이프(양방향통신)과, 이름 없는 파이프(단방향통신)을 지원한다.

Creating a Child Process with Redirected Input and Output


4. Mailslot - 통신
   메시지 큐잉을 지원하고, 비연결성이기 때문에 브로드 캐스팅을 지원한다. 사용하기가 간단하다.
   UDP와 같이 전송 보장을 지원하지 않고, 데이터크기가 400 바이트 이내라는 제한이 있다.

메일슬롯 생성과 읽기 (샘플)

메일 슬롯에 데이터 쓰기 (샘플)



5. SendMessage, PostMessage - 통신
   윈도우가 존재한다는 범위내에서만 사용가능한 통신이며, WPARAM, LPARAM 에 해당하는 두개의 정수형 타입 데이터의
   전송이 가능하다. 큐잉을 보장해주지만, 윈도가 있어야한다는 제약이 있다.

6. WM_COPYDATA - 통신
   5번과 마찬가지로 윈도우의 메시지를 이용한 통신 방식이다. 매우 사용하기 쉽다. 윈도우즈 메시지 기반이기 때문에,
   메시지 펌프 처리를 해줘야한다. 메시지 통신의 빈도가 낮고, 빨리 구현하는 것이 우선이라면 이 방법이 좋을 수 있다.
   다만 메시지를 받는 쪽이 윈도우 핸들이 가지고 있어야 한다.

WM_COPTDATA 샘플



7. Memory Mapped File - 공유
   Memory Mapped File도 프로세스 간 통신에 이용할 수 있다. 다른 IPC들이 Memory Mapped File를 이용해서 구현되므로,
   속도가 중요하다면, Memory Mapped File이 가장 나은 선택이다.
   대량의 데이터를 다룰 때 주로 사용되지만, 매핑된 메모리를 블럭단위로 사용하게 되므로, 상호 액세스에 대한 규정을
   잘 만들어 관리해야 한다.

8. DLL Shared Sections - 공유
   DLL을 만들고 공유 영역을 설정하여 데이터를 공유하는 방식이다. 일단 DLL을 작성해야 하기 때문에 간단한 통신을 위하여
   이러한 것을 만드는 것은 조금 비효율 적이라고도 할 수 있다.
   또한 윈도우에 같은 dll 이 있다면, 경로가 서로 달라 각각의 dll을 로드하게 되면 이러한 것도 무용지물이다.

9. DDE, NetDDE - 통신
   자료를 좀 찾아보니, DDE는 SendMessage 와 ATOM을 조합하여, 시스템 ATOM 테이블을 이용한 데이터 통신이란다.
   데이터가 있을 경우는 공유메모리를 생성하여, 해당 메모리 주소를 전달하는 방식이고, 이러한 조합을 몇가지 내부적인
   메시지로 감싸서 사용자가 쉽게 사용할 수 있도록 해결해준다.


MSDN에서 제공하는 ATOM을 이용한 DDE 구현



Posted by 까막백

댓글을 달아 주세요

  1. 2009/06/12 18:28  댓글주소  댓글쓰기 수정/삭제

    비밀댓글 입니다

    • 까막백 2009/06/14 23:29  댓글주소  수정/삭제

      글쎄요.. 저는 바이러스에 관한 부분을 말씀하시는 거라면..
      제쪽 계통이 아니라서 머라 첨부해 드릴 말이 없네요.
      죄송합니다. ㅠㅠ;;;

평소 별로 관심을 가져보지 못하던 영역의 자료가 올라와서 한번 살펴보았습니다.
웹쪽과는 인연이 없다보니 잘 살펴보지 않는 영역의 자룐데, 잘 정리된걸 보니 이뿌네요 ㅜㅜ;
취미로 해보기엔 좀 벅차고, 일로 떨어지면 헤딩이라도 해볼텐데.. ^^;;;

 익스플로러 보안설정 변경  | ActiveX/COM 2008-12-22 오후 5:21:55
최재권 (houseman)  최재권님께 메시지 보내기최재권님을 내 주소록에 추가합니다.최재권님의 개인게시판 가기  / 등록자 IP: xxx.xxx.244.109 번호: 8208   / 평점:  (9.0)  / 읽음:187

인터넷 익스플로러의 보안 설정 변경 관련.

 

1. 신뢰할수 있는 사이트 추가.

2. 구역별 보안등급 변경.

3. 임의의 선택한 보안 수준 변경.

 

 

1. 신뢰할수 있는 사이트 추가. &  2. 구역별 보안등급 변경.

 

 HRESULT hr;
 IInternetSecurityManager * pSecurityMgr;
 IInternetZoneManager * pZoneMgr;
 DWORD dwEnum, dwZoneCount;
 DWORD dwZone;
 ZONEATTRIBUTES zoneAttr;
 int nLevel = 2;
 
 CoInitialize(NULL);


 // 먼저 IinternetSecurityManager 인터페이스를 초기화한다.
 hr = CoCreateInstance(CLSID_InternetSecurityManager, NULL, CLSCTX_ALL, IID_IInternetSecurityManager, (void**)&pSecurityMgr);
 if (hr != S_OK)
 {
       CoUninitialize();
       return;
 }


 // 다음으로 IinternetZoneManager 인터페이스를 초기화한다.
 hr = CoCreateInstance(CLSID_InternetZoneManager, NULL, CLSCTX_ALL, IID_IInternetZoneManager, (void**)&pZoneMgr);
 if (hr != S_OK)
 {
       CoUninitialize();
       return;
 }
 dwEnum = 0;

 

 // Zone Enumerator를 초기화한다.
 pZoneMgr->CreateZoneEnumerator(&dwEnum, &dwZoneCount, 0);

 

 // 2번 존에 대한 정보를 얻는다. 2번 존이 신뢰할 수 있는 영역 존이다.
 pZoneMgr->GetZoneAt( dwEnum, nLevel, &dwZone);
 pZoneMgr->GetZoneAttributes(dwZone, &zoneAttr);

 

 // 지금 예제는 보통의 HTTP 사이트를 등록하는 것이기 때문에 HTTPS만을 등록해야 하는 제약 조건을 없앤다.
 if (zoneAttr.dwFlags &ZAFLAGS_REQUIRE_VERIFICATION)
 {
       // 서버 확인 부분을 뺀다.
       zoneAttr.dwFlags = (zoneAttr.dwFlags & ~(ZAFLAGS_REQUIRE_VERIFICATION));
 }

 

 // 현재 보안 설정이 낮음이 아니면 낮음으로 설정한다.
 if (zoneAttr.dwTemplateCurrentLevel != 0x10000)
 {
       zoneAttr.dwTemplateCurrentLevel = 0x10000;
       zoneAttr.dwTemplateMinLevel = 0x10000;
 }
 pZoneMgr->SetZoneAttributes(dwZone, &zoneAttr);
 


 // 등록 사이트
 CString strDomain = "http://www.devpia.com";

 

 // 이 값을 유니코드로 변경한다.
 BSTR bDomain = strDomain.AllocSysString();
 


 // IInternetSecurity 인터페이스의 SetZoneMapping 함수를 이용해 등록한다.
 hr = pSecurityMgr->SetZoneMapping(nLevel, bDomain, SZM_CREATE);


 if (hr == E_ACCESSDENIED)  // 존 설정이 서버 확인을 필요로 하는 곳이면
 {
       ::MessageBox(NULL, "등록하려는 영역이 서버 확인이 필요한 것으로 설정되어 있습니다.", "영역 추가 에러", MB_OK);
 }
 else if (hr == ERROR_FILE_EXISTS) // 이미 다른 영역으로 등록된 것이면
 {
       ::MessageBox(NULL, "등록하려는 주소가 이미 다른 영역으로 설정되어 있습니다.", "영역 추가 에러", MB_OK);
 }
 


 ::SysFreeString(bDomain);
 


 if (dwEnum != 0)
       pZoneMgr->DestroyZoneEnumerator(dwEnum);
 


 pSecurityMgr->Release();
 pZoneMgr->Release();
 CoUninitialize();

 

--------------------------------------------------------------------------------

위의 코드는 한기용(Keeyong@wisenut.com)님의 코드를 그대로 인용 하였음.

 

 

 

1,2 의 내용만으로 거의 모든 문제가 해결되리라 생각된다.

그러나 몇몇 보안 관련 부분은 보안 등급을 최소로 해도 문제가 해결되지 않는 경우가 있다.

이 경우엔 직접 원하는 보안관련 설정을 원하는 수준으로 변경 해야만 한다.

대표적인 예가 "안전하지 않은 것으로 표시된 ActiveX 컨트롤 초기화 및 스크립트"이다.

때때로 사소한 ActiveX들이 필요한 경우가 있는데 이런것들을 매번 서명을 받기도 번거로운 일이다.

이러한 문제를 해결하기위해서 보안수준을 변경할 필요가 있다.

 

이 항목을 직접 변경하는 코드를 살펴보자.

 

 

 

3. 임의의 선택한 보안 수준 변경.

CRegKey reg;     // #include <Atlbase.h>

if(reg.Open(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\2") == ERROR_SUCCESS)
{
     reg.SetValue((DWORD)0, "1201");  // 0:허용  1:확인  3:사용안함
     reg.Close();
}

if(reg.Open(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\2") == ERROR_SUCCESS)
{
     reg.SetValue((DWORD)0, "1201");  
     reg.Close();
}

 

----------------------------------------------------------------------

 

위의 예제는 [신뢰할수 있는 사이트>안전하지 않은 것으로 표시된 ActiveX 컨트롤 초기화 및 스크립트 => 사용] 으로 레지스트리를 직접 변경하는 코드이다.

 

그러나, 한기용(Keeyong@wisenut.com)님의 글에서는 레지스트리를 직접 편집하는것은 좋지 않은 방법이라고 설명하고 있다. 그 이유를 다음과 같이 설명하고 있다.

---------------------------------------------------------------

그 이유는 다음 버전의 IE에서도 레지스트리의 이 항목들을 URL 보안 관련

정보를 저장하는데 사용한다는 보장이 없기 때문이다. 따라서 URL 보안 영역

관련 인터페이스를 사용하는 것이 좋다.

---------------------------------------------------------------

 

따라서, 방법의 선택은 독자의 몫이다.

 

 

※ Zones > 2 는 신뢰할수 있는 사이트를 나타낸다.

  • Zone 0 (My computer 영역을 의미)
  • Zone 1 (Local intranet 영역을 의미)
  • Zone 2 (trusted sites 영역을 의미)
  • Zone 3 (Internet 영역을 의미)
  • Zone 4 (Restricted sites 영역을 의미)

     

    ※ 똑같은 내용이 hkey_local_machine과 hkey_current_user 두곳에 존재하는데 필자는 그 차이를 모르겠다. 따라서 두곳 모두 바꾸어 준다. 그러나 테스트 결과 hkey_current_user만 수정해도 무방하였다.

     

    ※ SetValue의 첫번째 파라미터는 값을 나타낸다.

         0:허용  1:확인  3:사용안함

     

    ※ SetValue의 두번째 파라미터는 값이름을 나타낸다. (1201 : 안전하지 않은 것으로 표시된 ActiveX 컨트롤 초기화 및 스크립트)

     

    참조

    엔트리 정의 기본값 권장값
    1001 서명된 ActiveX 컨트롤 다운로드 0 3
    1004 서명 안 된 ActiveX 컨트롤 다운로드 0 3
    1200 ActiveX 컨트롤과 플러그인 실행 0 1
    1201 안전하지 않은 것으로 표시된 ActiveX 컨트롤 초기화 및 스크립트 1 3
    1400 액티브 스크립팅 허용 0 1
    1402 자바 애플릿 스크립트 0 1
    1406 도메인 간의 데이터 소스 액세스 0 3
    1407 스크립트를 통한 붙여넣기 작업 허용 0 3
    1601 암호화되지 않은 폼 데이터 제출 0 1
    1604 폰트 다운로드 0 3
    1606 사용자 데이터 유지 0 3
    1607 서로 다른 도메인 간의 하위프레임 이동 0 3
    1802 파일의 드래그 앤 드롭이나 복사 및 붙여넣기 0 1
    1803 파일 다운로드 0 3
    1804 IFRAME에 프로그램과 파일 시작 0 3
    1E05 소프트웨어 채널 사용권한 30000 20000

     

    MSDN참고: http://technet.microsoft.com/ko-kr/library/cc700750.aspx

     

    ※ 보안관련 수정 내용은 새로 시작되는 익스플로러부터 적용된다.

    ----------------------------------------------------------------------------------------------

    최재권 jk9053@nate.com


  • Posted by 까막백

    댓글을 달아 주세요

    안냐세염. 까막임돠...

    회사에서 업무를 수행하다 보니 나오게된 결과물 입니다. 유틸리티성으로 만들게된 것인데
    상업적 사용만 아니라면 공개해도 문제 없다는 답변을 받고 올려봅니다.
    (상업적 사용이란, 회사에서 가공없이 업무에 사용하는것은 상관없습니다만, 재가공 하여 판매하는 것을 말함)
    (개인적인 욕심은 혹시 사용해보시고, 문제점이나 추가 기능에 대한 요구등을 얻을 수 있을까 하는 목적도 ㅎㅎ;;;)

    제목 그대로 테이블만 별도 파일로 떨구거나, 혹은 수행한 쿼리문의 결과를 파일로 저장하는 기능
    그리고, 반대로 저장된 파일을 다시 테이블로 넣는 기능을 제공하는 유틸리티입니다.
    (파일로 쓰거나, 테이블에 로딩하는 속도는 select into 와 비교했을 때 뒤지지 않습니다.)

    1. 알려진 사용상의 단점

    A. 위의 그림에서  보신바와 같이 테이블내에 혹은 수행된 쿼리 결과내에 여러개의 BLOB 형식의 데이터가 위치와 상관없이
    삽입되어 있더라도 동작 수행에 문제는 없으며
    , 단 한 컬럼당 BLOB 데이터의 크기가 100MB 정도까지만 지원되도록
    하는 제한 사항이 있습니다. (이는 일부러 제한을 둔것이 아니고, 아직까지 해결하지 못한 문제랍니다. -_-;;;)

    B. 테이블을 백업하였을 경우는 테이블의 자료구조가 100% 정확하게 파일에 설정되지만, 쿼리의 수행결과를 파일로 저장할 경우는
    select into 했을 때와 마찬가지로 호완가능한 구조로 저장되기 때문에, 테이블에 로딩했을 때 원본과 데이터 타입 일부가 다를 수
    있습니다. 예를 들면 smallmony 타입을 쿼리 결과로 파일에 저장했을 경우 decimal 로 저장됩니다.
    혹은 sysname 타입을 저장했을 경우는 nvarchar 로 저장되죠.

    백업 기능을 이용 -BACKUP -TABLE sysindexes 로 저장한 것과
    익스포트 기능을 이용 -EXPORT -QUERY "select * from sysindexes" 로 저장한 경우 테이블에 저장된 결과물은 동일하지만
    테이블의 자료형이 일부 다를 수 있습니다
    .

    반대로, -EXPORT 형태로 저장했을 경우는 해당 MSSQL 버전의 특정 자료형에 구속되지 않기 때문에 다른 버전의 MSSQL에도
    테이블로 로딩할 때 별 문제가 없습니다. (2005에서 만든 파일을 2000에도 로딩시킬 수 있음)


    C. 파일에 특정한 보안 로직이나 권한 제한등이 없기 때문에 외부로 유출되었을 경우 누구나 DB에 로딩 시킬 수 있습니다.
    관리상의 주의가 필요합니다. (보완해야할 대표적인 기능중에 1번째)

    D. 데이터파일에 대한 압축 기능이 제공되지 않습니다. (보완해야할 대표적인 기능중에 2번째)
    (MSSQL 2008 버전 부터는 지원하다는데.. 아직 접해보지는 못했음)

    2. 알려진 사용상의 장점
    MSSQL에서는 DTS 및 패키기 매니저, BCP등을 지원하는데 이렇게 떨궈진 파일들은 실제로 DB에 넣어놓기 전까지는
    내부 구조가 어떻게 생겨먹었는지, 무슨 이유로 만들어졌는지, 어떤 데이터가 들어있는지 아무도 모르죠..
    본 프로그램을 이용해서 저장할 경우는
    -PRINT 기능을 이용하여, DB에 로딩하지 않고서도 아래와 같이 필요한 정보를 볼 수 있습니다.
    파일이 생성된 시각, 만들어질 당시 접속한 데이터베이스, 유저명(암호는 당연히 기록되지 않음), 수행한 쿼리 및 대상 테이블
    컬럼의 구조 정보, 필요에 의해 기술한 코멘트, 그리고 첫번째 로우의 데이터 정보를 출력해줍니다.
    (하기사 이것때문에 만든것입니다. 장점은 흠.. -_-;;; 이게 다군요..)

    하나더 라고 한다면, 흠.. 쓸만할 만큼은 충분히 빠릅니다. GUI 툴처럼 복잡하지도 않고, BCP 처럼 다양한 옵션을 지원하진 않지만.
    성능하나만은 탁월하게 빠르다고 말씀드릴 수 있겠네요. 파일로 떨구는거나 테이블에 밀어 넣는거나... ^^;;;


            <이어진 화면>

    위의 그림에서 처럼, 생성시 넣어준 정보와 간단한 디스크립션, 컬럼 정보 및 저장된 내용중 첫번째 데이터를 출력해 줍니다.
    바이너리 및 이미지 데이터는 출력시 64바이트를 넘어가면 64바이트까지면 화면상에 출력해줍니다.

    특별하게 설치할건 없고, 실행파일 하나와 DLL 두개로 구성되어 있어서 그냥 압축 풀고 사용하시면 됩니다.
    <테스트환경: Windows 2003 Server 32Bit, Windows XP Home/Pro 32Bit, Windows Vista Home 32Bit, Windows 2008 Server 64Bit>

    QueryToFile.zip

    사용상의 문제점이나 활용 방안에 대한 의견이 있으시면 개발하는데 많은 도움이 되겠습니다. ^^;

    Posted by 까막백

    댓글을 달아 주세요

    1. 김범주 2008/12/12 21:09  댓글주소  댓글쓰기 수정/삭제

      안녕하세요. 정말 필요했던 프로그램 이였는데 감사합니다.
      다름이 아니라 이 프로그램으로 백업전략을 세우려다 몇가지 궁금한점이 생겼습니다.
      첫번째는 필드가 25개 이고 데이터가 12만건 들어있는 테이블이 있는데
      이 테이블을 백업시 46 rows write라는 문구가 뜨며 파일이 생성되지 않습니다.
      필드가 6개 정도 되는 다른 테이블의 경우 12만건 이상 진행하여도 문제 없이 진행되었습니다.
      또한 user_info란 테이블을 백업하니
      데이터가 만건이 채 되지 않는데 -1 rows write라는 문구가 떳습니다.
      혹시 이오류에 대해서 아시면 답변 부탁드립니다.

      또한 백업 후 그 내용을 복구 시키면 정말 빠른 시간에 기존 데이터를 백업하고 테이블 드랍후
      테이블을 다시 생성하게 되던데 primary key 속성을 줬던게 사라지는 현상이 있습니다.
      primary key를 보존한채 복구 시키는 방법은 없는지요?

      시간 되신다면 여기 댓글로 혹은 4xjida@naver.com으로 답변 부탁드리겠습니다.
      좋은 프로그램 감사합니다.

      • 까막백 2008/12/15 14:48  댓글주소  수정/삭제

        1. 백업에 문제가 생기는 테이블의 생성 스크립트를 올려줘 보세요.
        해당 테이블을 생성시켜서, 어떤 문제가 발생하는지 추적해 보도록 하겠습니다.
        2. 현재 제약조건이나, 인덱스 정보등은 백업 및 복구를 지원하지 않습니다.
        요 부분은 구지 필요하지 않아서 빼놓았는데, 기능에 추가해 보도록 하겠습니다.
        3. 참고로 해당 MSSQL 버전도 같이 올려주세욤..

    2. 김범주 2008/12/15 10:24  댓글주소  댓글쓰기 수정/삭제

      안녕하세요 까막백님 답변 주셔서 감사합니다.
      일단 해당 테이블의 생성 스크립트를 드리려다
      테이블을 삭제하고 테이블을 스크립트로 재생성 하니
      프로그램이 잘되더라구요.
      좀더 상황을 파악해서 테스트후 올려드리겠습니다.

      • 까막백 2008/12/15 14:50  댓글주소  수정/삭제

        네.. 몇몇 다양한 테이블을 대상으로 테스트를 하였지만,
        실무에 쓰이다 보면, NULL 처리 라든가, 사용자 정의 타입등에서 알 수 없는 다양한 에러가 발생할 수 있습니다.
        좀더 테스트 폭을 넓혀서 에러없는 유틸이 되도록 하겠습니다.

    ODBC 프로그래밍을 하다보면, BLOB 타입 데이터를 처리할 때 자주 만나게 되는 에러이다.
    예전에는 MS버그 려니, 하고 다음과 같은 방법으로 처리했었다.

    1. 테이블을 설계할 때 BLOB 타입은 항상 마지막으로 몬다.
       BLOB 타입이 여러개라면 모두 뒤쪽으로 몰아서 사용한다.

    2. ODBC는 때려치고, ADO나 OLEDB를 사용한다.
        (나는 ODBC를 꼭 써야하는 이유가 있으니 이 방법은 XXX 이다. -_-)
        (사실 ADO는 쬐끔 써봤는데... OLEDB는 써본적이 한번도 없다..헐~)

    위 두가지 방법이 인터넷 뒤져서 나온 해결법의 전부였다. MS포럼이나 KB 및 구글 뒤져바야
    나오는게 그게 그거이다. MS에 문의해보니 안갈켜준다 -_-;;;

    저 에러가 나오는 원인은 데이터 전송시 전송 효율을 올리기 위해서 미리 메모리를 할당해서 각
    컬럼별로 바인딩 해놓고 패치하게 되는데, 크기 범위가 정해지지 않은 BLOB 데이터를 중간에
    끼워넣게 되면 미리 준비된 메모리에 패치할 수 없기 때문이다.
    (모든 프로토콜 분야에서 전송 성능은 상당히 중요한 이슈이다.)

    이럴 경우 BLOB 영역은 0으로 리절브를 하게되고, 별도로 SQLGetData 를 이용해서 데이터를
    가져오게 되는데....
    이게 위치가 끝부분이 아니고, 중간부분에 가게되면 데이터 패치는 성공하지만, BLOB 데이터를
    가져오려 하면  제목에 보이는 잘못된 인덱스 입니다 라는 에러가 발생한다.

    한참 고민(3년간 사용하는 동안 -_-)하다가 문제의 원인을 추적해 보니, 패치하기 위하여 미리
    메모리를 바인딩 해놓는 부분을 생략하고, 그 때 그 때 데이터를 SQLGetData 로 가져오는
    방법
    을 생각해 봤다.

    흠.. 잘나온다 -_-;;;

    단, 미리 예비된 메모리에 덩어리로 패치하는게 아니기 때문에, 데이터 로우수가 많을 경우
    위 방법을 사용하면 성능 저하가 발생할 수 있으므로, 사용상에 주의를 할 필요가 있다.

    그나마 성능을 보전하기 위하여 머리를 굴려본걸 정리해 보면 다음과 같다.

    1. 컬럼 정보를 읽어올 때 BLOB가 있는지 검사한다.
    2. 모든 BLOB 컬럼이 뒤쪽에 몰려 있으면, 바인딩해서 리절브된 메모리에 패치하고, 나머지는 SQLGetData 로 긁어온다.
    3. 중간에 BLOB 컬럼이 끼어있으면, 바인딩을 안하고 모든 컬럼을 SQLGetData 로 긁어온다.

    이렇게 직접 구현하는 사람들이 많지 않겠지만, 그래도 혹시나 아직까지 쓰는 사람들이 있다면
    조금이라도 도움이 되겠죠 ^^;;;

    Posted by 까막백

    댓글을 달아 주세요

    프로그램을 작성하다 보면, 처음에 제일 문제였던것이 bio 설정에 관한 것이었다.
    컴파일해서 잘 돌아가다가 bio 에 멀 쓰던가 하면 OPENSSL_Uplink(00509010,07): no OPENSSL_Applink 
    위와 같은 에러가 발생하여 사람 참~ 난감하게 만든다.

    처음에는 저걸 해결하지 못해서, bio 쓰는 부분을 몽땅 털어버리는 무식한 노가다를 하기도 했었다.

    혹시나 비슷한 에러로 고생하는 사람이 없도록 http://www.openssl.org/support/faq.html 에 나와 있는 내용중에
    위 에러를 해결하기 위한 방법을 적어본다.

    아래는 해당 사이트 원문이다.
    결국은 프로그램을 설정할 때 스레드 모델을 아래 사항에 맞도록 설정해 주면 아주 미끈하게 잘 돌아간다 -_-;;;
    디버깅 하느라 날려버린 내 아까운 시간 흐~~

    2. I've compiled a program under Windows and it crashes: why?

    This is usually because you've missed the comment in INSTALL.W32. Your application must link against the same version of the Win32 C-Runtime against which your openssl libraries were linked. The default version for OpenSSL is /MD - "Multithreaded DLL".

    If you are using Microsoft Visual C++'s IDE (Visual Studio), in many cases, your new project most likely defaulted to "Debug Singlethreaded" - /ML. This is NOT interchangeable with /MD and your program will crash, typically on the first BIO related read or write operation.

    For each of the six possible link stage configurations within Win32, your application must link against the same by which OpenSSL was built. If you are using MS Visual C++ (Studio) this can be changed by:

     1. Select Settings... from the Project Menu.
     2. Select the C/C++ Tab.
     3. Select "Code Generation from the "Category" drop down list box
     4. Select the Appropriate library (see table below) from the "Use
        run-time library" drop down list box.  Perform this step for both
        your debug and release versions of your application (look at the
        top left of the settings panel to change between the two)
    

    Single Threaded /ML - MS VC++ often defaults to this for the release version of a new project. Debug Single Threaded /MLd - MS VC++ often defaults to this for the debug version of a new project. Multithreaded /MT Debug Multithreaded /MTd Multithreaded DLL /MD - OpenSSL defaults to this. Debug Multithreaded DLL /MDd

    Note that debug and release libraries are NOT interchangeable. If you built OpenSSL with /MD your application must use /MD and cannot use /MDd.

    As per 0.9.8 the above limitation is eliminated for .DLLs. OpenSSL .DLLs compiled with some specific run-time option [we insist on the default /MD] can be deployed with application compiled with different option or even different compiler. But there is a catch! Instead of re-compiling OpenSSL toolkit, as you would have to with prior versions, you have to compile small C snippet with compiler and/or options of your choice. The snippet gets installed as <install-root>/include/openssl/applink.c and should be either added to your application project or simply #include-d in one [and only one] of your application source files. Failure to link this shim module into your application manifests itself as fatal "no OPENSSL_Applink" run-time error. An explicit reminder is due that in this situation [mixing compiler options] it is as important to add CRYPTO_malloc_init prior first call to OpenSSL.


    Posted by 까막백

    댓글을 달아 주세요