[펌: http://blog.naver.com/hsshee?Redirect=Log&logNo=70037637328]


간혹 어떤 프로그램에서 LoadLibrary와 GetProcAddress API를 사용하여,

어떤 dll 내의 함수를 사용하는 경우가 있다.

 

LoadLibrary와 GetProcAddress의 원형을 살펴보자.

 

◈ HMODULE LoadLibrary( LPCTSTR lpFileName );

> 인자로 준 DLL을 현재 프로세스의 주소공간으로 mapping 시켜서 사용할 수 있도록 해주는 API.

 

◈ FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName);

> DLL에서 Export한 함수의 번지를 찾아서 그 함수를 사용할 수 있도록 그 함수의 포인터를 리턴해 주는 API.

 

 

1. DLL 내의 함수를 사용하기 위해서는,

먼저 LoadLibrary를 이용하여 DLL의 모듈 핸들을 리턴 받는다.

( HMODULE or HINSTANCE와 같은 핸들을 통해 리턴받으면 된다. )

 

인자는 DLL의 경로를 문자열로 넘겨주면 되고, 끝에 널문자가 있어야 한다는 걸 잊지 말자.

 

참고로, 반드시 리턴된 모듈 핸들이 NULL이 아닌지를 체크하는 습관을 들이도록 하자.

 

 

2. 유효한 모듈 핸들을 가지고,

GetProcAddress를 이용하여 DLL에서 Export한 함수를 가져오자.

 

이 때의 인자는 LoadLibrary를 통해서 리턴 받은 모듈 핸들과

그 DLL 내에서 사용하기 원하는 함수의 이름을 문자열로 넘겨준다. 이 때에도 끝에 널문자가 있어야 한다.

 

GetProcAddress를 수행하면 프로그램에서 선언한 함수포인터 변수에

DLL에서 Export한 함수의 주소가 리턴되어 이 프로그램에서 선언한 변수를 통하여

DLL 내의 해당 함수를 사용할 수 있게 되는 것이다.

 

만약에 인자가 정확하게 들어가지 않았다면, 역시 NULL이 리턴된다.

 

 

3. LoadLibrary와 같이 모듈 핸들을 받아서 DLL을 사용하였을 경우,

FreeLibrary API를 이용하는 습관을 들이도록 하자.

 

◈ BOOL FreeLibrary(HMODULE hLibModule);

>해당 DLL의 사용 카운트를 1 감소시키고 사용 카운트가 0이 되었을 때에 메모리에서 해당 DLL을 삭제해준다.

   리턴형은 BOOL인데, 이 때에 DLL을 삭제하는 데에 성공했다면 TRUE를, 실패했다면 FALSE를 리턴하는 것이다.

 
4. GetProcAddress에서 NULL이 리턴되는 경우 중,

Name Mangling으로 인한 경우가 있다. 이 때의 해결책은 다음과 같다.

 

DLL 프로그래밍한 프로젝트에서 export하는 함수를 선언하는 헤더에 다음과 같이 추가하여 Rebuild하면 된다.

 

 cpp dll 을 c type으로 바꿔주는 코드

 

#ifdef __cplusplus
extern "C"
{
#endif

 

// export할 함수

 

#ifdef __cplusplus
}
#endif

 

 

어떤 함수를 위의 코드를 이용하지 않고 빌드한 경우와 위의 코드를 추가하여 빌드한 경우에

각각의 dll파일을 Peview를 통하여 어떻게 함수명이 저장되는지 확인해보자.

 

원하는 함수명은 GetOpcodeFirstByte이다.

 

1) 위의 코드를 이용하지 않고 빌드한 경우,

 

2) 위의 코드를 추가하여 빌드한 경우,

 

1)의 경우에 GetProcAddress에서 Export할 함수의 문자열을 "GetOpcodeFisrtByte"로 넘겨주면,

실제 dll의 export된 함수명과 다르기 때문에 NULL이 리턴된다.

 

※ 위의 코드를 추가하는 습관을 들이도록 하자.

'NativeCode > api' 카테고리의 다른 글

printf, scanf 함수 포맷 문자열  (0) 2010.07.07
IP, TCP, UDP, ICMP Checksum 계산  (0) 2010.07.05
IpHlpApi MSDN  (0) 2010.07.04
SendARP  (0) 2010.07.03
[팁] Heap 메모리 검증하기.. | VC++ 일반  (0) 2010.05.09
이것보다 더 좋은 ListCtrl 사용법은 없을 듯 싶네요!!

1. 리스트컨트롤 추가 

2. 멤버변수 추가 
m_list 

3. 체크박스 레이아웃 
m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES | LVS_EX_GRIDLINES ); 

4. 초기화 
m_list.DeleteAllItems(); 

5. 칼럼명 설정 
m_list.InsertColumn(0, _T("번호"), LVCFMT_LEFT, 100, -1); 
m_list.InsertColumn(1, _T("제목"), LVCFMT_LEFT, 100, -1); 
m_list.InsertColumn(2, _T("작성자"), LVCFMT_LEFT, 100, -1); 
m_list.InsertColumn(3, _T("코멘트"), LVCFMT_LEFT, 100, -1); 
m_list.InsertColumn(4, _T("파일"), LVCFMT_LEFT, 100, -1); 
//칼럼 추가 인덱스, 칼람명, 정렬방향, 칼럼길이, 서브아이템 갯수 

6. 데이터 추가 
int seq = 0; 
CString seq_string; 
seq_string.Format(_T("%d"),seq); 
CString title=_T("test"); 
CString writer=_T("이대한"); 
CString comment=_T("없음"); 
CString file=_T("파일경로"); 

m_list.InsertItem(seq,seq_string); 
m_list.SetItem(seq,1,LVIF_TEXT,title,0,0,0,NULL); 
m_list.SetItem(seq,2,LVIF_TEXT,writer,0,0,0,NULL); 
m_list.SetItem(seq,3,LVIF_TEXT,comment,0,0,0,NULL); 
m_list.SetItem(seq,4,LVIF_TEXT,file,0,0,0,NULL); 

seq = 1; 
seq_string.Format(_T("%d"),seq); 
title=_T("test2"); 
writer=_T("이대한2"); 
comment=_T("있음"); 
file=_T("파일경로"); 

m_list.InsertItem(seq,seq_string); 
m_list.SetItem(seq,1,LVIF_TEXT,title,0,0,0,NULL); 
m_list.SetItem(seq,2,LVIF_TEXT,writer,0,0,0,NULL); 
m_list.SetItem(seq,3,LVIF_TEXT,comment,0,0,0,NULL); 
m_list.SetItem(seq,4,LVIF_TEXT,file,0,0,0,NULL); 


7. 아이템 선택(1개 이상 선택 및 확인) 
POSITION pos = m_list.GetFirstSelectedItemPosition(); 

if (pos == NULL) 
AfxMessageBox(_T("No items were selected!\n")); 
else 
{ 
while (pos) 
{ 
int nItem = m_list.GetNextSelectedItem(pos); 
CString temp = m_list.GetItemText(nItem,0); 
temp.Format(_T("%s seq가 선택됨"),temp); 
AfxMessageBox(temp); 


// you could do your own processing on nItem here 
} 
} 


8. 체크박스 전체 체크 
int nCount=m_list.GetItemCount(); 
for(int i = 0; i< nCount;i++) 
m_list.SetCheck(i); 

9. 체크박스 전체 해제 
//헤더파일에 
#ifdef ListView_SetCheckState 
#define ListView_SetCheckState(hwndLV,i,fCheck) \ 
ListView_SetItemState(hwndLV,i, \ 
INDEXTOSTATEIMAGEMASK((fCheck)+1),LVIS_STATEIMAGEMASK) 
#endif 

//소스파일에 
CListCtrl* tmp; 
tmp=&m_list; 
int nCount=m_list.GetItemCount(); 
for(int i = 0; i< nCount;i++) 
ListView_SetCheckState(tmp->GetSafeHwnd(),i,FALSE); 

10. 체크 확인(1개 이상) 
int nCount=m_list.GetItemCount(); 
for(int i =0 ; i
{ 
BOOL a = m_list.GetCheck(i); 
if(a==TRUE) 
{ 
CString temp = m_list.GetItemText(i,0); 
temp.Format(_T("%s seq가 선택됨"),temp); 
AfxMessageBox(temp); 
} 
} 



11. 데이터 삽입 
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다. 
int seq = 0; 
CString seq_string; 
seq_string.Format(_T("%d"),seq); 
CString title=_T("test"); 
CString writer=_T("이대한"); 
CString comment=_T("없음"); 
CString file=_T("파일경로"); 

m_list.InsertItem(seq,seq_string); 
m_list.SetItem(seq,1,LVIF_TEXT,title,0,0,0,NULL); 
m_list.SetItem(seq,2,LVIF_TEXT,writer,0,0,0,NULL); 
m_list.SetItem(seq,3,LVIF_TEXT,comment,0,0,0,NULL); 
m_list.SetItem(seq,4,LVIF_TEXT,file,0,0,0,NULL); 


12. 데이터 삭제 
POSITION pos = m_list.GetFirstSelectedItemPosition(); 

if (pos == NULL) 
AfxMessageBox(_T("No items were selected!\n")); 
else 
{ 
while (pos) 
{ 
int nItem = m_list.GetNextSelectedItem(pos); 
CString temp = m_list.GetItemText(nItem,0); 
temp.Format(_T("%s seq가 삭제됨"),temp); 
AfxMessageBox(temp); 
m_list.DeleteItem(nItem); 
// you could do your own processing on nItem here 
} 
} 

'NativeCode > mfc' 카테고리의 다른 글

MySQL C++, MFC에서 사용하기  (0) 2010.06.17
CDC 글 쓰기  (0) 2010.03.18
Font 바꾸기  (0) 2010.03.18
CFile  (0) 2010.03.18
Modal Vs Modless  (0) 2010.03.18

stl의 find와 sort를 사용하기란 함수 객체를 모르는 상태에서는 조금 어렵습니다.

함수 객체는 말 그대로 "함수이면서 객체" 입니다.

함수이면서 객체인 것은 어떤 것이 있을까요? 아래 코드를 보면 쉽게 알 수 있습니다.

(참조: http://www.hanb.co.kr/network/view.html?bi_id=1626 )

 

 

구조체 안에 함수를 담으면 함수 객체이냐고?? 일단은 그렇게 생각하세요. 그게 쉽습니다.

 

자 이제 그럼 stl::find()와 stl::sort()를 사용해 보도록 하겠습니다. 사용법은 위 함수객체만 안다면 너무나 쉽습니다.

아, 한가지 덧 붙이자면 find는 정수 같은 것은 바로 찾을 수 있지만 "사용자 정의 데이터 타입"은 find를 할 수 없습니다. 그래서 우리는 find_if함수를 사용해야 합니다. find_if 함수는 우리가 만든 데이터도 찾게 해줍니다.

 

소트 수행 전

 

소트 수행 후

 

 

100번 말보다는 한번 보는게 낫겠죠. 한번 보시고 돌려 보세요. 쉽게 아실 수 있을 겁니다.

 

결과입니다. 열공하세요!!


Bloger : moltak.net

'NativeCode > C++ STL' 카테고리의 다른 글

Algorithm  (0) 2010.03.18
list  (0) 2010.03.18
Sequential Container  (0) 2010.03.18
stl C++ Exception Class  (0) 2010.03.18
String  (0) 2010.03.18

출처 : http://blog.naver.com/pointer98/150046033124

포맷문자열

사용해야 인자타입

실제 내부 사용 변환 타입

기본진법

정밀도

%c 

int x

(unsigned char)x 

1바이트 문자

%lc 

wint_t x

wchar_t a[2] = {x} 

2바이트 확장 문자

%d

int x

(int)x 

10 

1 

%hd 

int x

(short)x 

10 

1 

%ld 

long x

(long)x 

10 

1 

%lld 

long long int x

(long long int)x

10

1

%i 

int x

(int)x 

10 

1 

%hi 

int x

(short)x 

10 

1 

%li 

long x

(long)x 

10 

1 

%lli 

long long int x

(long long int)x

10

1

%f 

double x

(double)x 

10 

6

%Lf 

long double x

(long double)x 

10 

6 

%F

double x

(double)x 

10 

6 

%LF

long double x

(long double)x 

10 

6 

%e 

double x

(double)x 

10 

6 

%Le 

long double x

(long double)x 

10 

6 

%E 

double x

(double)x 

10 

6 

%LE 

long double x

(long double)x 

10 

6 

%g 

double x

(double)x

10 

6 

%Lg 

long double x

(long double)x 

10 

6 

%G 

double x

(double)x 

10 

6 

%LG 

long double x

(long double)x 

10 

6 

%s 

char x[]

x[0]... 

1바이트 문자열

%ls 

wchar_t x[]

x[0]... 

2바이트 확장 문자열

%p 

void *x

(void *)x 

 

%u 

int x

(unsigned int)x 

10 

1 

%hu 

int x

(unsigned short)x

10 

1 

%lu 

long x

(unsigned long)x 

10 

1 

%llu 

long long int x

(unsigned long long int)x

10

1

%o 

int x

(unsigned int)x 

8 

1 

%ho 

int x

(unsigned short)x 

8 

1 

%lo 

long x

(unsigned long)x 

8 

1 

%llo

long long int x

(unsigned long long int)x

8 

1 

%x

int x

(unsigned int)x 

16 

1 

%hx 

int x

(unsigned short)x 

16 

1 

%lx 

long x

(unsigned long)x 

16 

1 

%llx 

long long int x

(unsigned long long int)x

16 

1 

%X 

int x

(unsigned int)x 

16 

1 

%hX 

int x

(unsigned short)x 

16 

1 

%lX 

long x

(unsigned long)x 

16 

1 

%llX

long long int x

(unsigned long long int)x

16 

1 

%n 

int * x

 

 

 

%hn 

short * x

 

 

 

%ln 

long * x

 

 

 

%% 

None

'%' 

%문자

 

 

 Escape문자

 

실제 문자

Escape 문자

"

\"

"문자

'

\'

'문자

? 

\? 

?문자

\ 

\\ 

\문자

BEL

\a 

Beep

BS

\b 

Backspace: 뒤로

FF

\f 

Form feed

NL

\n 

New line: 바꿈, buffer 비움

CR

\r 

Carriage return: 라인 처음으로

HT

\t 

수평 tab

VT

\v 

수직 tab

null 

\0 

null문자

code values

\d \dd \ddd

8진수 코드값

code values

\xh \xhh

16진수 코드값

 

 

 

scanf()함수의 포맷 플래그

 

포맷문자열

사용 데이터 변수 타입

호출되는 내부 변환함수

기본진법

%c

char x[]

1바이트 문자

%lc

wchar_t x[]

2바이트 확장 문자

%d

int * x

strtol

10

%hd

short * x

strtol

10

%ld 

long * x

strtol

10 

%lld 

long long int * x

strtol

10

%i 

int * x

strtol

10 

%hi 

short * x

strtol

10 

%li 

long * x

strtol

10 

%lli 

long long int * x

strtol

10 

%f 

float * x

strtod

10 

%lf 

double * x

strtod

10 

%Lf

long double * x

strtod

10 

%F

float * x

strtod

10 

%lF

double * x

strtod

10 

%LF

long double * x

strtod

10 

%e

float * x

strtod

10 

%le

double * x

strtod

10 

%Le

long double * x

strtod

10 

%E

float * x

strtod

10 

%lE

double * x

strtod

10 

%LE

long double * x

strtod

10 

%g 

float * x

strtod

10 

%lg 

double * x

strtod

10 

%Lg

long double * x

strtod

10 

%G

float * x

strtod

10 

%lG

double * x

strtod

10 

%LG

long double * x

strtod

10 

%s 

char x[] 

1바이트 문자열

%ls 

wchar_t x[] 

2바이트 확장 문자열

%u 

unsigned int * x

strtoul

10 

%hu 

unsigned short * x

strtoul

10 

%lu 

unsigned long * x

strtoul

10 

%llu 

unsigned long long int * x

strtoul

10 

%o 

unsigned int * x

strtoul

8 

%ho 

unsigned short * x

strtoul

8 

%lo 

unsigned long * x

strtoul

8 

%llo 

unsigned long long int * x

strtoul

8

%x 

unsigned int * x

strtoul

16 

%hx 

unsigned short * x

strtoul

16 

%lx 

unsigned long * x

strtoul

16 

%llx 

unsigned long long int * x

strtoul

16 

%X

unsigned int * x

strtoul

16 

%hX

unsigned short * x

strtoul

16 

%lX

unsigned long * x

strtoul

16 

%llX 

unsigned long long int * x

strtoul

16 

%p 

void ** x

 

 

%n 

int * x

 

 

%hn 

short * x

 

 

%ln 

long * x

 

 

%[...] 

char x[] 

 

 

%l[...] 

wchar_t x[] 

 

 

%% 

None

 

 

'NativeCode > api' 카테고리의 다른 글

LoadLibrary, GetProcAddress, FreeLibrary, Name Mangling 해결  (0) 2010.11.09
IP, TCP, UDP, ICMP Checksum 계산  (0) 2010.07.05
IpHlpApi MSDN  (0) 2010.07.04
SendARP  (0) 2010.07.03
[팁] Heap 메모리 검증하기.. | VC++ 일반  (0) 2010.05.09
패킷들은 checksum 필드를 갖고 있습니다. 이 필드를 이용해 이 패킷이 정상인지 아닌지 판단할 수 있습니다.
체크섬 계산은 간단히 할 수 있습니다.

알고리즘을 먼저 소개하겠습니다.


-- Ip Header checksum 계산--
1. ip header를 2바이트씩 자른다.
2. 체크섬 바이트를 0으로 초기화 합니다.
3. 체크섬 바이트에 짤린 바이트를 그대로 계속 더해갑니다. (sum += 각 2바이트)
4. 더해지는 sum은 4바이트여야 합니다. (올림이 생기기 때문에)
5. 다 더한다음 sum(4바이트) 중 윗 부분의 2바이트를 아랫부분의 2바이트에 다시 더합니다.
6. 다시 sum(4바이트) 중 윗 부분의 2바이트를 아랫부분의 2바이트에 다시 더합니다.

이와 같이 하는 이유는 올림이 다시 생기기 때문에 2번을 한다고 합니다.

7. 이제 2바이트가 된 sum을 1의 보수로 바꾸면 됩니다.



TCP, UDP, ICMP는 한가지 과정이 더 추가됩니다. IP Header의 정보가 필요합니다.
IP 헤더의 체크섬 계산법과 마찬가지로 20바이트에 해당하는 tcp 헤더의 값을 모두 더합니다.
데이터가 존재할경우 데이터 부분까지 더해 줍니다. 데이터가 홀수로 끝나는 부분은 주의해서 더해야 합니다.
다음으로 IP Header의 srcip, dstip를 2바이트로 잘라 더해줍니다.
부가적으로 IP Header의 protocol 필드, tcp 헤더의 길이를 더해줍니다.
여기서 tcp 헤더의 길이는 데이터 부분이 존재할경우 데이터 부분까지길이를 말합니다.
이후 IP의 체크섬과 마찬가지로 위 과정에서 발생한 케리값을 더해주는 과정을 거쳐 체크섬 계산이 완성됩니다.





UDP, ICMP의 경우는 TCP 체크섬 계산과 똑같습니다.

Bloger : moltak.net

'NativeCode > api' 카테고리의 다른 글

LoadLibrary, GetProcAddress, FreeLibrary, Name Mangling 해결  (0) 2010.11.09
printf, scanf 함수 포맷 문자열  (0) 2010.07.07
IpHlpApi MSDN  (0) 2010.07.04
SendARP  (0) 2010.07.03
[팁] Heap 메모리 검증하기.. | VC++ 일반  (0) 2010.05.09
iphlpapi 라이브러리의 msdn 소스 입니다.
굉장히 좋네요. 
NIC 이름과 설명 뿐만 아니라 아이피 NDIS 버젼등등 많은 정보가 나옵니다. 





Bloger: moltak.net

'NativeCode > api' 카테고리의 다른 글

printf, scanf 함수 포맷 문자열  (0) 2010.07.07
IP, TCP, UDP, ICMP Checksum 계산  (0) 2010.07.05
SendARP  (0) 2010.07.03
[팁] Heap 메모리 검증하기.. | VC++ 일반  (0) 2010.05.09
WSAGetLastError()  (0) 2010.04.06
이놈의 SendARP 사용법을 자꾸 까먹네요.ㅠㅠ
그래서 아예 사용법을 올리기로....
이 함수가 변수가 많이 필요해서 자꾸 헷갈립니다. 다른 분들도 그러시나;;
설마 나만?? ㅋㅋ


SendARP는 한 세그먼트에 있는 다른 시스템의 MAC을 얻을 때 사용합니다.
MAC 주소는 48비트이기 때문에 [unsigned char] 가 6개 필요하겠네요.
그리고 아이피 주소를 [unsigned int] 형으로 바꿔 줄 필요가 있습니다.
아래의 소스에서 MAC 주소를 알아낼 대상은 "192.168.0.2" 인 것을 알 수 있네요.

변수만 잘 보신다면 쉽게 사용하실 수 있을 듯 합니다.


Bloger: moltak.net

'NativeCode > api' 카테고리의 다른 글

IP, TCP, UDP, ICMP Checksum 계산  (0) 2010.07.05
IpHlpApi MSDN  (0) 2010.07.04
[팁] Heap 메모리 검증하기.. | VC++ 일반  (0) 2010.05.09
WSAGetLastError()  (0) 2010.04.06
Sock 정보들  (0) 2010.04.04

안녕하세요. 오랜만의 블로깅입니다. 이제 부지런히 해야겠어요.ㅋㅋ

이놈의 게으름… 귀차니즘….

 

오늘의 주제는 MySql을 C++이나 MFC에서 사용하기 입니다.

Visual Studio를 깔면 자동으로 MSSQL이 설치됩니다. 이것을 C++, MFC에서 사용할 수 있죠.

하지만 전 개인적으로 MySql, SQLite같은 것들을 더 좋아합니다. ㅋㅋ

 

설치법은 굉장히 간단하니 한번 시작해 보도록 할게요.

 

http://www.mysql.com/ 에 들어 가시면 Downloads 탭이 있습니다.


 

들어가셔서 Community Server 버전을 다운 받으세요.


 

플랫폼은 Windows 버전으로 다운 받으세요.

 

다운을 다 받은 후 실행하면 설치 옵션이 있는데 그 때 꼭 Custom Setup을 선택하세요.

그 후 C Include Files / Lib Files 를 선택하세요.

 

 

여기까지 하시면 Library 설치는 다 끝났습니다. 이제 사용만 하면 됩니다.

 

VS의 도구->옵션에 들어가셔서 Library 설정하시면 바로 사용가능합니다.

 

 

저는 위 그림처럼 include와 lib를 설정했습니다.

 

 

이제 예제 소스를 보도록 하죠.

MySql Library는 다음과 같은 순서로 진행됩니다.

mysql_init() -> mysql_real_connect() -> mysql_query() -> mysql_store_result() -> mysql_fetch_row() -> mysql_free_result() -> mysql_close()

다른 DB Library와 비슷한 순서로 진행됨을 알 수 있습니다.

 

 

 

위와 같이 하면 잘 됩니다. ^^

모두들 즐프 하세요!!ㅋㅋ

 

 

 

Bloger: moltak.net

'NativeCode > mfc' 카테고리의 다른 글

D-H,appy :: MFC list control 사용  (2) 2010.07.28
CDC 글 쓰기  (0) 2010.03.18
Font 바꾸기  (0) 2010.03.18
CFile  (0) 2010.03.18
Modal Vs Modless  (0) 2010.03.18

혹시나 싶어서 여기 게시판에서 검색하니 나오지 않더군요..

모르시는 분들 계실까봐 적어봅니다...

 

 

보통 잘못된 메모리 영역에 쓰기를 하는 경우(memory corruption) 오류가 즉시 발생하지 않습니다..

이런 오류를 잡기가 참으로 난감한데요..

 

그럴 때 _ASSERT(_CrtCheckMemory()); 를 많이 사용하셨을 겁니다.

 

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

_CrtCheckMemory()에 대한 사용법은.. 아실거라고 가정하고..

DCRT를 사용하기 위한 준비 작업만 간단하게 적어봅니다.

 

//stdafx.h 제일 처음에 선언

#define _CRTDBG_MAP_ALLOC   

 

//stdafx.h 제일 마지막에 선언

#include <crtdbg.h>    

// main() 제일 처음에 선언

 _CrtSetDbgFlag(
  _CRTDBG_CHECK_ALWAYS_DF
  |_CRTDBG_LEAK_CHECK_DF
  |_CRTDBG_ALLOC_MEM_DF
  |_CRTDBG_DELAY_FREE_MEM_DF
  );

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

 

그런데 _CrtCheckMemory()를 사용해서 커럽션 발생 유무는 확인 할 수 있어도

어느 부분이 문제인지는 알 수 없습니다.

결국  _ASSERT(_CrtCheckMemory()); 를 의심되는 코드에 넣어가면서 범위를 좁히게 되는데요..

그럼에도 불구하고 문제를 해결하기 난감한 상황이 올 수 있습니다.

 

그럴 때 아래와 같은 코드를 사용하면 효험을 볼 수 있습니다.

 

_ASSERT(_CrtIsMemoryBlock(buffer, size, NULL,NULL,NULL));

 

_CrtIsMemoryBlock()는 지정된 메모리 영역이 올바른 힙 메모리인지 검증합니다.

 

스택 메모리나.. 이런 것은 안 됩니다. 힙만 됩니다.

 

그래서.. IOCP와 같은 비동기로 메모리에 쓰기 요청을 하기 전에 위와 같은 코드로 검증을 하면..

커럽션이 발생할 것인지 미리 알 수 있습니다.

 

상큼하게..

 

 void Transfer::PreRequest(BYTE* buffer, int size)
 {
    _ASSERT(_CrtIsMemoryBlock(buffer, size, NULL,NULL,NULL));

 }

 

위와 같이 전달 받은 포인터로 작업을 하는 함수의 제일 상단에 검증하는 코드를 넣어주면...

뭔가 있어 보입니다... ^^

 

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

퇴근 시간이 조금 남아서 예제 하나 만들어 봤습니다.

진작 만들걸.. 하는 후회가 듭니다... T_T

 

#define _CRTDBG_MAP_ALLOC

 

#include <tchar.h>

#include <memory>

 

#include <crtdbg.h>

 

int _tmain(int argc, _TCHAR* argv[])

{

        _CrtSetDbgFlag(

               _CRTDBG_CHECK_ALWAYS_DF

               |_CRTDBG_LEAK_CHECK_DF

               |_CRTDBG_ALLOC_MEM_DF

               |_CRTDBG_DELAY_FREE_MEM_DF

               );

 

 

        int* p=new int[10];

        const int size=sizeof(int)*10;

 

        //p[9]까지유효하기때문에p[10]에무언가를기록하면

        //Memory Corruption이다커럽션이발생한이후에

        //_CrtCheckMemory()를실행하면false를리턴한다.

        _ASSERT(true==_CrtCheckMemory());

        p[10]=0;

        _ASSERT(false==_CrtCheckMemory());

 

        //할당한후_CrtIsMemoryBlock로영역을체크하면true를리턴

        _ASSERT(true==_CrtIsMemoryBlock((const void *)p, size, NULL, NULL, NULL));

 

        //할당된 메모리의 제일 처음이 아닌 임의의 주소를 검사하면 false 리턴

       //찾아보지는 않았지만 메모리 할당 테이블을 유지하고 있는데..

       //이 테이블에서 p+2로 탐색이 안 되서 그럴거라 추측합니다.

       //아시는 분의 제보 기다립니다.

        _ASSERT(false==_CrtIsMemoryBlock((const void *)p+2, size-2, NULL, NULL, NULL)); 

 

        //pdelete 한후에_CrtIsMemoryBlock로영역을체크하면

        //올바르지않은힙영역이기때문에false가리턴된다.

 

        delete[] p;

        _ASSERT(false==_CrtIsMemoryBlock((const void *)p, size, NULL, NULL, NULL));

 

        return 0;

}

'NativeCode > api' 카테고리의 다른 글

IpHlpApi MSDN  (0) 2010.07.04
SendARP  (0) 2010.07.03
WSAGetLastError()  (0) 2010.04.06
Sock 정보들  (0) 2010.04.04
소켓 옵션  (0) 2010.04.01


윈속을 사용할 때 WSAGetLastError()함수를 굉장히 많이 사용하게 됩니다. 함수를 호출해서 그때의 반환 값을 보고 코딩을 다시 하거나 소스를 바꾸거나 하죠. 반환 값은 int형인데 그것을 보고 인터넷에서 검색해서 사용하게 됩니다. 
하지만 사용자가 직접 메시지를 넣어 줄 수도 있겠죠?? 그때 아래와 같은 것이 필요합니다. 좋네요 ^^

10004, "블럭킹 윈속이 WSACancelBlockingCall 함수에서 취소되었습니다 ") );

10009, "잘못된 기술자(소켓 핸들)이다 ") );
10013, "브로드캐스트 어드레스를 위한 데이터그램 소켓의 접속시도가 setsockopt 함수로 SO_BROADCAST가 설정되어있지 않은 상태에서 실패 했습니다. ") );
10014, "name 또는 namelen 매개변수가 올바른 형태가 아닙니다. ") );
10022, "accept 하기 전에 listen 함수가 불려지지 않았습니다. ") );
10024, "새로운 소켓에 할당하기 위한 소켓 기술자가 더 이상 남아있지 않습니다 ") );
10035, "소켓 함수가 비블럭킹 모드로 동작중이다 ") );
10036, "블록화 함수가 호출 되는 동안 부적절한 소켓 함수가 호출되었다 ") );
10037, "이미 완료된 비동기 명령에 대한 취소가 시도됨 ") );
10038, "지정한 기술자가 소켓 기술자가 아닙니다 ") );
10039, "해당 함수에 목적지 어드레스가 필요하지만 제공되지 않았음 ") );
10040, "수신된 메시지가 지정된 버퍼에 저장하기에 너무 커서 손실 되었습니다 ") );
10041, "지정된 프로토콜이 잘못되었거나 이 소켓에 대해서 잘못된 형식입니다 ") );
10042, "알 수 없는 옵션이거나, 지원지지 않는 옵션을 사용했습니다. ") );
10043, "지정된 프로토콜이 지원되지 않는 형식입니다 ") );
10044, "지정된 소켓 타입이 지정한 어드레스 체계에서 지원되지 않는 형식입니다 ") );
10045, "socket이 연결지향형 서비스(SOCK_STREAM)형태가 아닙니다. ex) listen이 UDP socket에서 호출 ") );
10046, "지정된 프로토콜 체계가(PF_*) 지원되지 않습니다 ") );
10047, "지정된 어드레스 체계가(AF_*) 지원되지 않습니다 ") );
10048, "지정한 어드레스(IP)가 이미 사용중이다 ") );
10049, "지정된 어드레스는 로컬 머신에서 사용할 수가 없다 ") );
10050, "네트웍 서브 시스템에 에러가 발생했습니다 ") );
10051, "원격 시스템까지 네트웍이 도달할 수 없습니다 ") );
10052, "연산이 진행되고 있는 도중 접속이 끊겨버렸습니다. ") );
10053, "연결이 out-of-band나 다른 실패 때문에 끊어져 버렸습니다. ") );
10054, "원격 연결지에서 "hard"나 "abortive" 종료를 수행해서 리셋되었습니다. ") );
10055, "윈도우 소켓 시스템의 버퍼 공간이 모자라거나, 애플리케이션에 의해 API에게 제공된 공간이 너무 작아서 요청된 정보를 저장 할 수가 없음 ") );
10056, "지정된 소켓이 이미 연결 되어 있음 ") );
10057, "지정된 소켓이 이미 연결 되어 있지 않음 ") );
10058, "소켓이 셧다운(shutdown()) 되었습니다. ") );
10059, "지정한 함수에 대한 인자가 너무 많음") ); 
10060, "접속 시도가 시간초과 되었습니다. ") );
10061, "접속시도가 강제로 종료되었습니다 ") );
10062, "") );                  
10063, "") );                  
10064, "원격 호스트가 다운 되었음 ") );
10065, "네트웍 시스템 장애 등에 의해서 원격호스트까지도 달 할 수 없습니다.") );
10091, "네트워크 서브 시스템이 아직 통신할 준비가 되어 있지 않음(WSAStartup()이 반환)") ); 
10092, "요청한 윈도우즈 소켓 버전이 현재 윈도우즈 소켓 시스템에서 지원하지 않습니다. ") );
10093, "이 함수를 사용하기 전에 성공적인 WSAStartup 함수의 호출이 없었습니다.") ); 
11001, "호스트를 찾아낼 수 없습니다.") );
11002, "요청된 정보가 발견 되지 않음") );
11003, "회복할 수 없는 에러발생") );
11004, "잘못된 이름(name)으로 아무런 데이터가 기록되지 않았습니다. ") );

'NativeCode > api' 카테고리의 다른 글

SendARP  (0) 2010.07.03
[팁] Heap 메모리 검증하기.. | VC++ 일반  (0) 2010.05.09
Sock 정보들  (0) 2010.04.04
소켓 옵션  (0) 2010.04.01
Broadcasting 예제  (0) 2010.03.31
WSAAsyncSelect() 소켓의 I/O 상태 변화 즉, 연결요청, 데이터 수신, 송신 버퍼의 사용가능 등의 이벤트를 시스템이 메시지를 통하여 알려주도록 요청함 
WSAAsyncGetHostByAddr() 호스트 주소로부터 호스트 정보를 얻음 
WSAAsyncGetHostByName() 호스트 이름으로부터 호스트 정보를 얻음 
WSAAsyncGetProtoByName() 프로토콜 이름으로부터 프로토콜 번호를 얻음 
WSAAsyncGetProtoByNumber() 프로토콜 번호로부터 프로토콜 이름을 얻음 
WSAAsyncGetServByName() 서비스 이름으로부터 서비스 정보를 얻음 
WSAAsyncGetServByPort() 포트번호로부터 서비스 정보를 얻음 


DWORD GetWindowThreadProcessId (
HWND       hWnd;
        LPDWORD lpdwProcessId
);
HWND 값을 이용하여 프로세스 ID를 알려주는 함수이다.
hWnd              - PID를 얻고자 하는 윈도우의 핸들
lpdwProcessId - 반환받을 PID의 포인터, NULL로 설정할 경우 PID는 리턴값으로 반환된다.

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

WSAAsyncGetServByPort

getservbyport

두 함수는 서비스 이름이 등록된 파일에서 입력된 포트번호에 대한 서비스를 리턴해 준다.

http://blog.naver.com/lseykwang?Redirect=Log&logNo=100071270266

위 사이트에서 검색..

WSAAsyncGetProtoByNumber()

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

문법 HANDLE WSAAsyncGetServByPort(HWND hwnd, UINT wMsg, int port, const char *proto, char *buf, int buflen) ; 

인자

hwnd 함수 호출이 완료되었을 때 메시지를 수신할 윈도우의 핸들 
wMsg 함수 호출이 완료되었을 때 보낼 메시지 
port 서비스 포트 번호 
proto 프로토콜의 이름을 가리키는 문자열의 포인터 
buf servent구조체를 수신할 버퍼의 포인터 
buflen 버퍼의 크기 
설명

getservbyport()의 비동기형 함수로 포트 번호와 프로토콜 이름에 해당하는 서비스 정보 구조체 servent를 만들고 응용 프로그램 윈도우 hwnd에게 메시지 wMsg를 보낸다. 

리턴값

성공 비동기 태스크 핸들 
실패 0 
WSAGetLastError() :

WSANOTINITALISED, WSAENETDOWN, WSAEINPROGRESS, WSAEINVAL WSAEALREADY 

 

windows socket system call 요약 
-----------------------------------------------------------------------------------------------------

BOOL WINAPI GetFileInformationByHandle(
  __in   HANDLE hFile,
  __out  LPBY_HANDLE_FILE_INFORMATION lpFileInformation
);
핸들을 이용해서 파일 정보를 얻어오는 것
hFile : 정보를 얻고자 하는 파일의 핸들
lpFileInformation : BY_HANDLE_FILE_INFORMATION구조체 변수의 주소를 전달. 여기로 전달되는 주소의 변수에 파일 정보가 채워짐.

typedef struct _BY_HANDLE_FILE_INFORMATION {
  DWORD    dwFileAttributes; //파일의 특성 정보
  FILETIME ftCreationTime; //파일의 생성 날짜
  FILETIME ftLastAccessTime; //파일에 마지막으로 액세스 한 날짜
  FILETIME ftLastWriteTime; //파일에 마지막으로 수정한 날짜
  DWORD    dwVolumeSerialNumber;
  DWORD    nFileSizeHigh; //대용량이 이 변수도 읽어와야함
  DWORD    nFileSizeLow; //4G이하 파일의 크기를 얻어올 때
  DWORD    nNumberOfLinks;
  DWORD    nFileIndexHigh;
  DWORD    nFileIndexLow;
} BY_HANDLE_FILE_INFORMATION, *PBY_HANDLE_FILE_INFORMATION;

=================================================
DWORD WINAPI GetFullPathName(
  __in   LPCTSTR lpFileName,
  __in   DWORD nBufferLength,
  __out  LPTSTR lpBuffer,
  __out  LPTSTR *lpFilePart
);
파일 이름을 통해서 파일경로 정보를 얻어야 할 때 사용
lpFileName : Full Path를 확인하고자 하는 파일 이름을 전달한다.
nBufferLength : Full Path를 저장할 버퍼에 저장 가능한 문자열 길이를 지정한다.(바이트크기가 아니라 문자열 길이!)
lpBuffer : Full Path를 저장할 버퍼의 주소값을 지정한다.
lpFilePart : Full Path가 문자열로 버퍼에 저장된 이후, 버퍼의 특정 위치를 가리키는 포인터 값이 저장(특정 위치부터 출력하면 파일명 나옴)
=================================================






함 수 기 능
 select() 소켓의 상태 변화(읽기, 쓰기, 오류 발생)를 알려줌
 gethostbyaddr() 호스트 주소로부터 호스트 정보를 얻음
 gethostbyname() 호스트 이름으로부터 호스트 정보를 얻음
 getprotobyname() 프로토콜 이름으로부터 프로토콜 번호를 얻음
 getprotobynumber() 프로토콜 번호로부터 프로토콜 이름을 얻음
 getservbyname() 서비스 이름으로부터 서비스 정보를 얻음
 getservbyport() 포트번호로부터 서비스 정보를 얻음

위와 같은 blocking 함수들은 소켓의 동작 모드에 관계없이 항상 블록될 수 있는 함수이다
이러한 함수를 사용할 때 프로그램이 블록되는 문제를 해결하기 위하여, 윈속에서는 이들 blocking 함수와 같은 기능을 수행하면서 실제로는 비동기 모드로 동작하는 즉, 함수 실행결과를 비동기적으로 알려주는 비동기 함수들을 제공하고 있다. 
  함 수  기 능
 WSAAsyncSelect() 소켓의 I/O 상태 변화 즉, 연결요청, 데이터 수신, 송신 버퍼의 사용가능 등의 이벤트를 시스템이 메시지를 통하여 알려주도록 요청함 
 WSAAsyncGetHostByAddr() 호스트 주소로부터 호스트 정보를 얻음 
 WSAAsyncGetHostByName() 호스트 이름으로부터 호스트 정보를 얻음
 WSAAsyncGetProtoByName()  프로토콜 이름으로부터 프로토콜 번호를 얻음
 WSAAsyncGetProtoByNumber() 프로토콜 번호로부터 프로토콜 이름을 얻음
 WSAAsyncGetServByName()  서비스 이름으로부터 서비스 정보를 얻음
 WSAAsyncGetServByPort() 포트번호로부터 서비스 정보를 얻음







'NativeCode > api' 카테고리의 다른 글

[팁] Heap 메모리 검증하기.. | VC++ 일반  (0) 2010.05.09
WSAGetLastError()  (0) 2010.04.06
소켓 옵션  (0) 2010.04.01
Broadcasting 예제  (0) 2010.03.31
UDP Server, Client  (0) 2010.03.31

소켓을 사용하다 보면 옵션이 필요한 경우가 있습니다.

책에서 나오는 예제를 보면 가장 처음에는 send, recv buffer 크기 변경하는게 나오더 군요.

하지만 더 많죠. 거기에 대해서 블로깅 하겠습니다.

 

소켓 옵션 설정하기

 

소켓 옵션 얻기

 

일단 소켓 옵션 사용하는 것은 아래와 같은 함수를 사용합니다.

인자를 설명하자면

소켓, 변경할 옵션의 프로토콜 레벨, 변경할 옵션 이름, 변경할 옵션의 값을 저장한 버퍼, 전달하는 옵션의 바이트 단위 길이.

이렇게 5개가 되네요.

 

소켓 옵션은 크게 세 개가 있습니다.

SOL_SOCKET

IPPROTO_IP

IPPROTO_TCP

소켓에 대한 가장 일반적인 옵션

IP Protocol의 옵션

TCP Protocol의 옵션

 

소켓 옵션 - SOL_SOCKET

 

소켓 옵션 - IPPROTO_IP

 

소켓 옵션 - IPPROTO_TCP

 

SO_REUSEADDR 옵션

소켓을 사용해서 함수를 만들다 보면 bind가 되지 않는 현상을 자주 봤을 것입니다.. 이것은 4Way-handshaking 과정 때문인데 서버가 먼저 강제 종료 된다면 소켓이 바로 종료가 되는 것이 아니라 TIME-WAIT 상태로 빠지게 되기 때문에 그렇습니다. (Handshaking 참조) 그래서 현재 bind가 되어 있는 상태이기 때문에 다시 bind 하려고 하면 에러가 나는 것이죠. 이 상태는SOL_SOCKET의 SO_REUSEADDR을 바꿈으로써 해결 할 수 있습니다.  

실제로 SO_REUSEADDR의 옵션은 default값은 0(FALSE)입니다. 그래서 반드시 TRUE옵션을 주는 것을 추천을 합니다.

'NativeCode > api' 카테고리의 다른 글

WSAGetLastError()  (0) 2010.04.06
Sock 정보들  (0) 2010.04.04
Broadcasting 예제  (0) 2010.03.31
UDP Server, Client  (0) 2010.03.31
Server Socket  (0) 2010.03.19
이번엔 브로드캐스팅 예제입니다. 자신이 속한 세그먼트에 데이터를 한방에 보낼 때 사용하는 프로토콜 이죠.
일단 예제를 보시죠. 아주 아주 간단합니다.
이제까지와 다른 점이라곤 소켓에 옵션을 주는 것 밖에 없는데요. 그 옵션들은 다음에 포스팅 하도록 하겠습니다.


Sender
 

Receiver
 

'NativeCode > api' 카테고리의 다른 글

Sock 정보들  (0) 2010.04.04
소켓 옵션  (0) 2010.04.01
UDP Server, Client  (0) 2010.03.31
Server Socket  (0) 2010.03.19
Client Socket  (0) 2010.03.19
UDP의 가장 큰 특징은 비 연결성이라는 것이겠죠? 아래 소스를 보시면 알겠지만 접속 하는 것이 없어요. 서버는 바인드에서 끝나서 데이터를 받기 위해 recvfrom을 호출하고 있고 클라이언트는 sendto로 전송대기만 하고 있음.
TCP 보다 조금더 간단하게 생겼음

Server

 


Client
 

'NativeCode > api' 카테고리의 다른 글

소켓 옵션  (0) 2010.04.01
Broadcasting 예제  (0) 2010.03.31
Server Socket  (0) 2010.03.19
Client Socket  (0) 2010.03.19
① WSAStartup  (0) 2010.03.19
소켓 소스입니다. 이번엔 Server 구요. 가장 기본형이죠.

'NativeCode > api' 카테고리의 다른 글

Broadcasting 예제  (0) 2010.03.31
UDP Server, Client  (0) 2010.03.31
Client Socket  (0) 2010.03.19
① WSAStartup  (0) 2010.03.19
소켓 함수 정리  (0) 2010.03.19
우리가 자주 사용하게 되는 소켓. 근데 보통 책에 있는 모양대로 사용하게 되죠? MFC는 CSocket이 있고 QT에는 QSocket이 있어서 WinSock을 직접 조작해서 플그래밍 할 일이 별로 없죠. 

하지만 가끔 WinSock을 이용해서 프로그래밍 할 필요가 있는데요. 그때마다 책에 있는 것을 참조 해서 사용하죠. 그리고 책에는 대부분 C스타일로 사용하고 있구요. 

근데 C++ 플그래밍 하는데 C스타일은 좀 어색하지 않나요? 나만 그런가? ㅋㅋ 암튼 전 아래와 같은 방식으로 사용한답니다. C++ 스타일이라고 해봐야 try/catch가 섞여 있는 것 뿐이지만요. 이 블로그 찾아보면 Exeption을 클래스로 전달하는 것으로 대신하고 있는 소스도 있습니다. 참고 하실 분은
http://moltak.tistory.com/entry/C-Style-Socket 여기를 참고 하세요.

암튼 모두들 즐프~~ 하세요ㅋㅋ

 

'NativeCode > api' 카테고리의 다른 글

UDP Server, Client  (0) 2010.03.31
Server Socket  (0) 2010.03.19
① WSAStartup  (0) 2010.03.19
소켓 함수 정리  (0) 2010.03.19
C++ Style Socket  (0) 2010.03.19

WSAData wsaData;

int nError;


nError = WSAStartup( MAKEWORD( 2, 2 ), &wsaData );

if( nError != 0 )

// error 

'NativeCode > api' 카테고리의 다른 글

Server Socket  (0) 2010.03.19
Client Socket  (0) 2010.03.19
소켓 함수 정리  (0) 2010.03.19
C++ Style Socket  (0) 2010.03.19
Client Source  (0) 2010.03.19

소켓 초기화 시키기

보통 WSAStartup -> socket -> closesocket -> WSACleanup 순으로 이뤄진다.

서버 WSAStartup -> socket -> bind -> listen ->  accept -> closesocket -> WSACleanup

클라 WSAStartup -> socket -> connect -> closesocket -> WSACleanup


WSADATA wsaData;

SOCKET sock;

SOCKADDR_IN addr;


WSAStartup( MAKEWORD( 2, 2 ), &wsaData );

sock = socket( AF_INET, SOCK_STREAM, 0 );


memset( ( void * )&addr, 0, sizeof( SOCKADDR_IN ) );

addr.sin_family = AF_INET;

addr.sin_addr.s_addr = inet_addr( IP_ADDRESS );

addr.sin_port = htons( PORT_NUMBER );


closesocket( sock );

WSACleanup();

'NativeCode > api' 카테고리의 다른 글

Client Socket  (0) 2010.03.19
① WSAStartup  (0) 2010.03.19
C++ Style Socket  (0) 2010.03.19
Client Source  (0) 2010.03.19
Server Source  (0) 2010.03.19

Snap6.png


바로 쓸수 있는 건 아니고... 이런 식으로 만들면 된다. 앞에 있는 예제는 api 에서는 저렇게 하고 C++ 문법으로는 이렇게 한다.

나는 Exception Class를 직접 만들어서 사용했으며 그 예외를 호출쪽에서 처리할 수 있도록 제작하였다.

기존 api 방식의 문법은 눈에 잘 들어오지 않는 단점이 있으며 위의 방법은 눈에 잘 들어오고 구조적이라는 장점이 있다.

'NativeCode > api' 카테고리의 다른 글

① WSAStartup  (0) 2010.03.19
소켓 함수 정리  (0) 2010.03.19
Client Source  (0) 2010.03.19
Server Source  (0) 2010.03.19
winsock 자신의 아이피 알아내기  (0) 2010.03.19

#include <stdio.h>
#include <winsock2.h>

#pragma comment(lib,"wsock32.lib")

void main()
{
    SOCKET s;
    SOCKADDR_IN sin;
    WSADATA wsaData;
    if(WSAStartup(MAKEWORD(2,0),&wsaData) != NO_ERROR)
    {
        printf("WSAStartup failed, error code : %d\n",WSAGetLastError());
        return ;
    }

    s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

    if(s == INVALID_SOCKET)
    {
        printf("make socket failed, error code : %d\n",WSAGetLastError());
        WSACleanup();
        return ;
    }

    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = inet_addr("127.0.0.1");
    sin.sin_port = htons(912);

    if(connect(s,(struct sockaddr*)&sin,sizeof(sin)) != NO_ERROR)
    {
        printf("connect failed, error code = %u \n",WSAGetLastError());
        closesocket(s);
        WSACleanup();
        return ;
    }

    if(closesocket(s) != NO_ERROR)
    {
        printf("remove socket failed, error code : %u\n",WSAGetLastError());
        WSACleanup();
        return ;
    }

    if(WSACleanup() != NO_ERROR)
    {
        printf("WSACleanup failed, error code = &u\n",WSAGetLastError());
        return ;
    }

    printf("127.0.0.1의 912번 포트에 접속을 성공하셨습니다.\n");
}

'NativeCode > api' 카테고리의 다른 글

소켓 함수 정리  (0) 2010.03.19
C++ Style Socket  (0) 2010.03.19
Server Source  (0) 2010.03.19
winsock 자신의 아이피 알아내기  (0) 2010.03.19
Winsock 상대방 아이피, 포트 알아내기  (0) 2010.03.19

#include <stdio.h>
#include <winsock2.h>

void main()
{

    // Initialize Winsock.
    WSADATA wsaData;
    int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
    if ( iResult != NO_ERROR )
        printf("Error at WSAStartup()\n");

    // Create a socket.
    SOCKET m_socket;
    m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );

    if ( m_socket == INVALID_SOCKET )
    {
        printf( "Error at socket(): %ld\n", WSAGetLastError() );
        WSACleanup();
        return;
    }

    // Bind the socket.
    sockaddr_in service;

    service.sin_family = AF_INET;
    service.sin_addr.s_addr = inet_addr( "127.0.0.1" );
    service.sin_port = htons( 27015 );

    if ( bind( m_socket, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR )
    {
        printf( "bind() failed.\n" );
        closesocket(m_socket);
        return;
    }

    // Listen on the socket.
    if ( listen( m_socket, 1 ) == SOCKET_ERROR )
        printf( "Error listening on socket.\n");

    // Accept connections.
    SOCKET AcceptSocket;

    printf( "Waiting for a client to connect...\n" );
    while (1)
    {
        AcceptSocket = SOCKET_ERROR;
        while ( AcceptSocket == SOCKET_ERROR )
        {
            AcceptSocket = accept( m_socket, NULL, NULL );
        }
        printf( "Client Connected.\n");
        m_socket = AcceptSocket;
        break;
    }

    // Send and receive data.
    int bytesSent;
    int bytesRecv = SOCKET_ERROR;
    char sendbuf[32] = "조산 서버";
    char recvbuf[32] = "";

    bytesRecv = recv( m_socket, recvbuf, 32, 0 );
    printf( "Bytes Recv: %ld\n", bytesRecv );

    bytesSent = send( m_socket, sendbuf, strlen(sendbuf), 0 );
    printf( "Bytes Sent: %ld\n", bytesSent );

    printf("Recv Buf: %s\n", recvbuf);

    return;
}

'NativeCode > api' 카테고리의 다른 글

C++ Style Socket  (0) 2010.03.19
Client Source  (0) 2010.03.19
winsock 자신의 아이피 알아내기  (0) 2010.03.19
Winsock 상대방 아이피, 포트 알아내기  (0) 2010.03.19
IPHLPAPI(IP Helper API) functions  (0) 2010.03.19

char lHostName[ 255 ];

PHOSTENT lHostInfo;

char *IpBuffer;

WSADATA wsaData;


if( WSAStartup( MAKEWORD( 2,0 ), &wsaData ) == 0 )

{

if( gethostname( lHostName, 255 ) == 0 )

{

if( ( lHostInfo = gethostbyname( lHostName ) ) != NULL )

{

IpBuffer = inet_ntoa( *( struct in_addr * )*lHostInfo->h_addr_list );

}

}

}


CString LocalAdap;
 CString LocalMac;
 CString LocalIP;
 CString LocalSub;
 CString LocalGate;

 PIP_ADAPTER_INFO pAdapterInfo;
 PIP_ADAPTER_INFO pAdapter = NULL;

 DWORD dwRetVal = 0;
 BOOL m_bBreak = FALSE;

 pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));
 unsigned long ulOutBufLen = sizeof(IP_ADAPTER_INFO);

 UpdateData(true);

 if(GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) != ERROR_SUCCESS)
 {
  GlobalFree(pAdapterInfo);
  pAdapterInfo = (IP_ADAPTER_INFO*)malloc(ulOutBufLen);
 }

 if((dwRetVal=GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR)
 {
  pAdapter = pAdapterInfo;
  while(pAdapter)
  {
   LocalAdap.Format (_T("%s"), (CA2W)pAdapter->Description);
   m_listbox.AddString(LocalAdap);

   LocalMac.Format (_T("MAC : %02X-%02X-%02X-%02X-%02X-%02X"),pAdapter->Address[0],pAdapter->Address[1], 
    pAdapter->Address[2], pAdapter->Address[3], pAdapter->Address[4], pAdapter->Address[5]);
   m_listbox.AddString((_T("MAC :"), LocalMac));

   LocalIP.Format (_T("IP : %s"), (CA2W)pAdapter->IpAddressList.IpAddress.String);
   m_listbox.AddString(LocalIP);

   LocalSub.Format (_T("Local : %s"), (CA2W)pAdapter->IpAddressList.IpMask.String);
   m_listbox.AddString(LocalSub);

   if(pAdapter->Next == NULL)
   {
    m_bBreak = TRUE;
    break;
   }
   pAdapter = pAdapter->Next;
  }
 }

'NativeCode > api' 카테고리의 다른 글

Client Source  (0) 2010.03.19
Server Source  (0) 2010.03.19
Winsock 상대방 아이피, 포트 알아내기  (0) 2010.03.19
IPHLPAPI(IP Helper API) functions  (0) 2010.03.19
CSocket 과 CAsyncSocket에서 Thread문제  (0) 2010.03.19

클라이언트의 접속을 받아 드릴때 accept 함수를 사용하게 된다.

이때 accept 함수에 인자를 세개를 넣게 되는데 두번째 인자에 클라이언트에 대한 정보를 넣을 수 있다.

이때 세번째 인자에는 받아야할 데이터 크기에 대한 변수를 넣어야 한다. 데이터 크기가 다르면

뻑날 수도 있다. ㅋ


sockaddr_in clientInfo = { 0 };

int addrsize= sizeofsockaddr_in );
client = accept( m_Socket, ( sockaddr * )&clientInfo, &addrsize );


printf( "ip = %s  port = %d\n", inet_ntoa( clientInfo.sin_addr ),  ntohs( ( short )clientInfo.sin_port ) );

'NativeCode > api' 카테고리의 다른 글

Server Source  (0) 2010.03.19
winsock 자신의 아이피 알아내기  (0) 2010.03.19
IPHLPAPI(IP Helper API) functions  (0) 2010.03.19
CSocket 과 CAsyncSocket에서 Thread문제  (0) 2010.03.19
HTTP 긁어오기 (소스파일 有)  (0) 2010.03.19

IPHLPAPI(IP Helper API) functions

Headers


#include <winsock2.h>
#include <iphlpapi.h>

Library

  • WS2_32.lib
  • IPHLPAPI.lib

Adapter Configuration


DWORD
GetAdapterIndex(
  LPWSTR AdapterName,
  PULONG IfIndex
);

DWORD WINAPI
GetAdaptersAddresses(
  ULONG Family,
  DWORD Flags,
  PVOID Reserved,
  PIP_ADAPTER_ADDRESSES pAdapterAddresses,
  PULONG pOutBufLen
);

DWORD
GetAdaptersInfo(
  PIP_ADAPTER_INFO pAdapterInfo,
  PULONG pOutBufLen
);

DWORD
GetPerAdapterInfo(
  ULONG IfIndex,
  PIP_PER_ADAPTER_INFO pPerAdapterInfo,
  PULONG pOutBufLen
);

DWORD
GetUniDirectionalAdapterInfo(
  PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS pIPIfInfo,
  PULONG dwOutBufLen
);

ARP


DWORD
CreateIpNetEntry(
  PMIB_IPNETROW pArpEntry
);

DWORD
CreateProxyArpEntry(
  DWORD dwAddress,
  DWORD dwMask,
  DWORD dwIfIndex
);

DWORD
DeleteIpNetEntry(
  PMIB_IPNETROW pArpEntry
);

DWORD
DeleteProxyArpEntry(
  DWORD dwAddress,
  DWORD dwMask,
  DWORD dwIfIndex
);

DWORD
FlushIpNetTable(
  DWORD dwIfIndex
);

DWORD
GetIpNetTable(
  PMIB_IPNETTABLE pIpNetTable,
  PULONG pdwSize,
  BOOL bOrder
);

DWORD
SendARP(
  IPAddr DestIP,
  IPAddr SrcIP,
  PULONG pMacAddr,
  PULONG PhyAddrLen
);

DWORD
SetIpNetEntry(
  PMIB_IPNETROW pArpEntry
);

Network Interface


DWORD
GetFriendlyIfIndex(
  DWORD IfIndex
);

DWORD
GetIfEntry(
  PMIB_IFROW pIfRow
);

DWORD
GetIfTable(
  PMIB_IFTABLE pIfTable,
  PULONG pdwSize,
  BOOL bOrder
);

DWORD
GetInterfaceInfo(
  PIP_INTERFACE_INFO pIfTable,
  PULONG dwOutBufLen
);

DWORD
GetNumberOfInterfaces(
  PDWORD pdwNumIf
);

DWORD
SetIfEntry(
  PMIB_IFROW pIfRow
);

IP, ICMP


DWORD
GetIcmpStatistics(
  PMIB_ICMP pStats
);

DWORD
GetIpStatistics(
  PMIB_IPSTATS pStats
);

BOOL
IcmpCloseHandle(
  HANDLE IcmpHandle
);

HANDLE
IcmpCreateFile(void);

DWORD
IcmpParseReplies(
  LPVOID ReplyBuffer,
  DWORD ReplySize
);

DWORD
IcmpSendEcho(
  HANDLE IcmpHandle,
  IPAddr DestinationAddress,
  LPVOID RequestData,
  WORD RequestSize,
  PIP_OPTION_INFORMATION RequestOptions,
  LPVOID ReplyBuffer,
  DWORD ReplySize,
  DWORD Timeout
);

DWORD
IcmpSendEcho2(
  HANDLE IcmpHandle,
  HANDLE Event,
  FARPROC ApcRoutine,
  PVOID ApcContext,
  IPAddr DestinationAddress,
  LPVOID RequestData,
  WORD RequestSize,
  PIP_OPTION_INFORMATION RequestOptions,
  LPVOID ReplyBuffer,
  DWORD ReplySize,
  DWORD Timeout
);

DWORD
SetIpStatistics(
  PMIB_IPSTATS pIpStats
);

DWORD
SetIpTTL(
  UINT nTTL
);

IP address configuration


DWORD
AddIPAddress(
  IPAddr Address,
  IPMask IpMask,
  DWORD IfIndex,
  PULONG NTEContext,
  PULONG NTEInstance
);

DWORD
DeleteIPAddress(
  ULONG NTEContext
);

DWORD
GetIpAddrTable(
  PMIB_IPADDRTABLE pIpAddrTable,
  PULONG pdwSize,
  BOOL bOrder
);

DWORD
IpReleaseAddress(
  PIP_ADAPTER_INDEX_MAP AdapterInfo
);

DWORD
IpRenewAddress(
  PIP_ADAPTER_INDEX_MAP AdapterInfo
);

Network configuration


DWORD
GetNetworkParams(
  PFIXED_INFO pFixedInfo,
  PULONG pOutBufLen
);

Notification


DWORD
NotifyAddrChange(
  PHANDLE Handle,
  LPOVERLAPPED overlapped
);

DWORD
NotifyRouteChange(
  PHANDLE Handle,
  LPOVERLAPPED overlapped
);

Routing


DWORD
CreateIpForwardEntry(
  PMIB_IPFORWARDROW pRoute
);

DWORD
DeleteIpForwardEntry(
  PMIB_IPFORWARDROW pRoute
);

DWORD WINAPI
EnableRouter(
  HANDLE* pHandle,
  OVERLAPPED* pOverlapped
);

DWORD
GetBestInterface(
  IPAddr dwDestAddr,
  PDWORD pdwBestIfIndex
);

DWORD
GetBestRoute(
  DWORD dwDestAddr,
  DWORD dwSourceAddr,
  PMIB_IPFORWARDROW pBestRoute
);

DWORD
GetIpForwardTable(
  PMIB_IPFORWARDTABLE pIpForwardTable,
  PULONG pdwSize,
  BOOL bOrder
);

BOOL
GetRTTAndHopCount(
  IPAddr DestIpAddress,
  PULONG HopCount,
  ULONG MaxHops,
  PULONG RTT
);

DWORD
SetIpForwardEntry(
  PMIB_IPFORWARDROW pRoute
);

DWORD WINAPI
UnenableRouter(
  OVERLAPPED* pOverlapped,
  LPDWORD lpdwEnableCount
);

TCP, UDP


DWORD
GetExtendedTcpTable(
  PVOID pTcpTable,
  PDWORD pdwSize,
  BOOL bOrder,
  ULONG ulAf,
  TCP_TABLE_CLASS TableClass,
  ULONG Reserved
);

DWORD
GetExtendedUdpTable(
  PVOID pUdpTable,
  PDWORD pdwSize,
  BOOL bOrder,
  ULONG ulAf,
  UDP_TABLE_CLASS TableClass,
  ULONG Reserved
);

DWORD
GetOwnerModuleFromTcpEntry(
  PMIB_TCPROW_OWNER_MODULE pTcpEntry,
  TCPIP_OWNER_MODULE_INFO_CLASS Class,
  PVOID Buffer,
  PDWORD pdwSize
);

DWORD
GetOwnerModuleFromTcp6Entry(
  PMIB_TCP6ROW_OWNER_MODULE pTcpEntry,
  TCPIP_OWNER_MODULE_INFO_CLASS Class,
  PVOID Buffer,
  PDWORD pdwSize
);

DWORD
GetOwnerModuleFromUdpEntry(
  PMIB_UDPROW_OWNER_MODULE pUdpEntry,
  TCPIP_OWNER_MODULE_INFO_CLASS Class,
  PVOID Buffer,
  PDWORD pdwSize
);

DWORD
GetOwnerModuleFromUdp6Entry(
  PMIB_UDP6ROW_OWNER_MODULE pUdpEntry,
  TCPIP_OWNER_MODULE_INFO_CLASS Class,
  PVOID Buffer,
  PDWORD pdwSize
);

DWORD
GetTcpStatistics(
  PMIB_TCPSTATS pStats
);

DWORD
GetTcpTable(
  PMIB_TCPTABLE pTcpTable,
  PDWORD pdwSize,
  BOOL bOrder
);

DWORD
SetTcpEntry(
  PMIB_TCPROW pTcpRow
);

DWORD
GetUdpStatistics(
  PMIB_UDPSTATS pStats
);

DWORD
GetUdpTable(
  PMIB_UDPTABLE pUdpTable,
  PDWORD pdwSize,
  BOOL bOrder
);

'NativeCode > api' 카테고리의 다른 글

winsock 자신의 아이피 알아내기  (0) 2010.03.19
Winsock 상대방 아이피, 포트 알아내기  (0) 2010.03.19
CSocket 과 CAsyncSocket에서 Thread문제  (0) 2010.03.19
HTTP 긁어오기 (소스파일 有)  (0) 2010.03.19
FTP  (0) 2010.03.19

1.요약

CSocket / CAsyncSocket을 생성한 곳이 아닌 다른 Thread로 넘겨 처리할 경우 CSocket이 가진 Thread state가 변해 에러가 발생합니다.

예를들어 한쪽에서는 Listen을 하여 클라이언트 Socket을 Accept하고, Thread를 생성시켜 Socket전송을 맡길 경우에 Thread문제를 해결하는 방법을 소개하겠습니다.


2.본문

방법은 간단합니다.
Accept한 Socket을 Deatch시키고 거기에서 나온 handle을 Thread로 넘김니다.
그리고 Thread에서 handle을 Attach시켜 CSocket / CAsyncSocket 개체 인스턴스를 만들어 사용하면 됩니다. 

'NativeCode > api' 카테고리의 다른 글

Winsock 상대방 아이피, 포트 알아내기  (0) 2010.03.19
IPHLPAPI(IP Helper API) functions  (0) 2010.03.19
HTTP 긁어오기 (소스파일 有)  (0) 2010.03.19
FTP  (0) 2010.03.19
HTTPS GET - Download HTML from HTTPS URL  (0) 2010.03.19

MFC Source HTTP_소스_긁어오기.zip

#include "AFXINET.H"

CInternetSession* pSession = NULL;
CStdioFile* pFile = NULL;
TCHAR szError[1024] = {0};

TRY 
{
  pSession = new CInternetSession;
  pFile = pSession->OpenURL( "http://www.devpia.com" );
}
CATCH( CInternetException, pEx )
{
  pEx->GetErrorMessage( szError, 1024 );
}

END_CATCH

if( pFile != NULL )
{
  //여기서 웹페이지 내용을 가지고 처리
  //HTTP를 호출했을 시
  CHttpFile* pHttpFile = (CHttpFile*)pFile;
  
  /*원하는 코드를 실행한다.*/
  // pHttpFile->ReadString(CString DataType);
  
  delete pHttpFile;
  pHttpFile = NULL;
  pFile = NULL;
}

if( pSession != NULL )
{
  //pSession->Close(); //CInternetSession 소멸자가 알아서 호출함
  delete pSession;
  pSession = NULL;
}

/*
  파라미터를 GET 방식으로 넘기시려면 ...

  CInternetSession::OpenURL()로 접속할 URL과 파라미터 넘겨주면,
  CStdioFile 포인터를 넘겨 주거든요. 그냥 파일 처럼 처리하시면 되겠네요.

  OpenURL("http://localhost/test.asp?name=하나")
  이런 식으로 처리하실 수 있습니다


  파라미터를 POST 방식으로 넘기시려면 ...
  CInternetSession::GetHttpConnection()으로 HTTP 커넥션 맺어 주시고,
  CHttpConnection::OpenRequest()로 URL에 접속해서,
  CHttpFile::AddRequestHeaders()로 헤더와 POST 정보를 추가해서 ...
  CHttpFile::SendRequest()로 데이터 날려 주시면 됩니다.
*/

'NativeCode > api' 카테고리의 다른 글

IPHLPAPI(IP Helper API) functions  (0) 2010.03.19
CSocket 과 CAsyncSocket에서 Thread문제  (0) 2010.03.19
FTP  (0) 2010.03.19
HTTPS GET - Download HTML from HTTPS URL  (0) 2010.03.19
CkLibrary  (1) 2010.03.19

void OnDownLoad()

{

CInternetSession session;

CFtpConnection *pConnection = NULL;

CFtpFileFind *pFileFind = NULL;

CString csStr;

CString csFileName;

BOOL bContinue;


try

{

pConnection = session.GetFtpConnection( "220.67.202.123", "h7", "h7" );

pConnection->GetCurrentDirectory( csStr );

pFileFind = new CFtpFileFind( pConnection );

bContinue = pFileFind->FindFile( csStr );


while( bContinue )

{

bContinue = pFileFind->FindNextFile();

csFileName = pFileFind->GetFileName();


if( !pFileFind->IsDirectory() )

{

pConnection->GetFile( csFileName, csFileName );

}

}

catch (CFileException* e)

{

e->ReportError();

}

catch(CInternetException *e)

{

e->ReportError();

}

}


pConnection->Close();

delete pFileFind;

}


Snap1.bmp

'NativeCode > api' 카테고리의 다른 글

CSocket 과 CAsyncSocket에서 Thread문제  (0) 2010.03.19
HTTP 긁어오기 (소스파일 有)  (0) 2010.03.19
HTTPS GET - Download HTML from HTTPS URL  (0) 2010.03.19
CkLibrary  (1) 2010.03.19
Sendarp 사용법  (0) 2010.03.19

Snap8.png   옆의 소스는 https 에서 페이지 정보를 얻어오는 함수이다. wininet 을 이용해서 https 의 소스를 얻어올 수 있다곤 하는데 잘 모르겠더라. 계속 검색중 우연히 찾은 사이트에서 얻은 소스이다. 그 홈페이지는 자체 개발한 라이브러리를 이용해서 쉽게 구현하고 있었다.

// Any string unlock the component for the 1st 30-days.이 부분은 뭘 나타내는지 잘 모르겠다.

'NativeCode > api' 카테고리의 다른 글

HTTP 긁어오기 (소스파일 有)  (0) 2010.03.19
FTP  (0) 2010.03.19
CkLibrary  (1) 2010.03.19
Sendarp 사용법  (0) 2010.03.19
Event  (0) 2010.03.19

인터넷에서 mfc https 를 검색하다 우연히 찾아낸 홈페이지.

유용한 정보가 굉장히 많이 들어있다. ㅋㅋ

http://www.example-code.com/mfc/https_get_with_cert.asp

굉장히 좋더라 일단 가보자ㅋㅋ


'NativeCode > api' 카테고리의 다른 글

FTP  (0) 2010.03.19
HTTPS GET - Download HTML from HTTPS URL  (0) 2010.03.19
Sendarp 사용법  (0) 2010.03.19
Event  (0) 2010.03.19
Deadlock 4가지 조건  (0) 2010.03.19
ULONG   ulMACAddr[2],
ulSize = 6;
LPBYTE pBuffer;

if (SendARP(inet_addr(_T("207.219.70.31")), 0,
ulMACAddr, &ulSize) == NO_ERROR)
{
pBuffer = (LPBYTE) ulMACAddr;

// access the address one byte at a time m_strText.Format("%02X:%02X:%02X:%02X:%02X:%02X\r\n",
pBuffer[0],
pBuffer[1],
pBuffer[2],
pBuffer[3],
pBuffer[4],
pBuffer[5]);

m_edit1.ReplaceSel(m_strText);
}
#include <IPHlpApi.h> 를 잊지 말아야할것

'NativeCode > api' 카테고리의 다른 글

HTTPS GET - Download HTML from HTTPS URL  (0) 2010.03.19
CkLibrary  (1) 2010.03.19
Event  (0) 2010.03.19
Deadlock 4가지 조건  (0) 2010.03.19
Synchronization Function  (0) 2010.03.19

+ Recent posts