1. C/C++프로그래밍과 ::CreateThread
윈도우가 제공하는 CreateThread 함수는 스레드를 생성하는 함수이다. 하지만 C/C++ 로
코드를 작성하는 경우에는 CreateThread 를 사용해서는 안 되고, 마이크로소프트 C/C++
runtime-library 에서 제공하는 _beginthreadex 함수를 사용해야 한다. 다른 컴파일러
에서도 ::CreateThread 함수를 대체할 만한 함수를 제공할 것이며, 반드시 컴파일러에 의해
제공되는 다른 함수를 사용해야 한다.


2. 멀티 스레드 안전한 C/C++ Library
역사적으로 C runtime-library 개발자는 멀티 스레드 어플리케이션에서 C runtime-library 를
사용하였을 때 발생하는 문제에 대해서는 전혀 고려하지 않았다. 멀티 스레드 어플리케이션
에서 전통적인 C runtime-library 를 사용하였을 때 문제가 발생할 수 있다.
따라서 Microsoft 는 이러한 문제를 해결하기 위해서 스레드 안전한 C/C++ runtime-library 를
제공하고 있다.
멀티 스레드 안전한 C/C++ run-time library 함수는 다른 스레들로부터 영향을 받지 않도록
자신을 호출한 스레드의 데이터 블록에만 접근 가능하게 한다.


3. Single-thread C/C++Library 와 Multi-thread C/C++ Library
Single-thread C/C++Library 는 단일 스레드 전용의 함수들을 말하고,
Multi-thread C/C++ Library 는 멀티 스레드 전용의 함수들을 말한다.

※ Visual Studio 2008 에서는 Multi-thread C/C++ Library 만 지원한다.
즉 더 이상 단일 스레드 전용의 C/C++ 라이브러리는 제공하지 않는다.





4. _beginthread 와 _endthread
_beginthread 함수는 새로운 스레드를 생성하고 난 후 바로 ::CloseHandle 함수를 호출하여
새로 생성된 스레드의 핸들을 제거하게 된다. 따라서 _beginthread 함수 호출 이후에 이 스레드
핸들에 접근 할 수 없게 된다.
_beginthread 함수의 이런 동작은 Win32의 상세함을 숨기기 위해 고안되었으나 결국 버그가
되어버린 함수이다. 따라서 마이크로소프트는 이러한 버그를 수정한 _beginthreadex 함수를 만들
게 되었다.
_beginthread 함수는 ::CreateThread, _begintheadex 함수에 비해 매개변수의 개수가 적다.
보안특성을 가진 스레드를 생성할 수 없으며, 일시 정지된 상태의 스레드도 생성할 수 없고,
스레드의 ID 값을 얻을 수도 없다.
_beginthread 함수는 스레드가 종료되면 자동으로 _endthread 함수를 호출 하는데 이 함수는
어떠한 매개변수도 가지고 있지 않기 때문에 스레드의 종료 코드는 항상 0 이다.


5. _beginthreadex 와 _endthreadex
::CreateThread 함수의 문제점을 보완하기 위해 C/C++ runtime-library 가 제공하는 스레드를
생성하는 함수로서 각 스레드 별로 적절한 구조의 데이터 블록을 생성해 준다.
::CreateThread 함수와 동일한 매개변수를 가지고 있지만 매개변수의 이름과 형태가 일치 하지
않는다. C/C++ run-time library 가 윈도우의 자료형에 의존성을 가지지 않도록 개발했기 때문
이다.
_beginthreadex 함수의 반환값은 ::CreateThread 함수의 반환값과 같은 새로 생성된 스레드의
핸들 값이다. 하지만 자료형이 정확하게 일치하지는 않기 때문에 적절하게 형변환을 해줘야 한다.
_beginthreadex 함수는 _beginthread 함수와는 달리 내부적으로 새로 생성한 스레드의 핸들을
제거하지 않기 때문에 명시적으로 ::CloseHandle 함수를 호출해 주어야 한다.
_beginthreadex 함수에 의해 생성된 스레드가 종료되면 _endthreadex 함수가 자동으로 호출.


6. ::AfxBeginThread
MFC 에서 스레드(Worker thread, User interface thread)를 생성하는 함수이다.
::AfxBeginThread 함수는 실제 스레드 생성을 수행하지 않는다. 스레드 생성을 위한 객체를
생성하고 스레드 생성을 위해 CWinThread::CreateThread 함수를 호출하는 것이 전부이다.
실제 스레드 생성은 CWinThread::CreateThread 함수 내부에 구현되어 있다.
CWinThread::CreateThread 함수는 내부적으로 _beginthreadex 함수를 호출하여 스레드를
생성한다.

출처 : http://six605.tistory.com/277
Posted by pkss
,

[VC++] 외부 프로그램 부르기 ( WinExec, CreateProcess, ShellExcute, ShllExcuteEx )Jedi's Move

출처: 데브피아


Windows 95의 출현과 함께 문서의 개념이 중요성을 띠게 되었다. 이제는 실행파일이라는 개념이 좀더 복잡해 지고 단순히 구동한다는 의미를 떠나 아주 방대한 개념으로 자리 잡고 있다.
문서라고 하는 것은 시스템의 네임스페이스의 일부인 보다 일반적인 객체를 말하고자 하며, 이문서에 대하여 '열기(open)', '인쇄(print)', '탐색(explore)', '찾기(find)'를 하는 프로그램이 있다. 다시 말해서, 문서라는 것은 그것에 대해서 프로그램이 어떤 동사(Verb)를 실행할 수 있는 모든 아이템을 말한다.

지금의 프로그램 실행자의 모체였던 WinExec()에서 ShellExecuteEx()라는 함수로 그 진행이 옮겨가는 이유도 이해 따른다.

이 장에서는 다음과 같은 것들을 다룰 것이다.
1. WinExec()와 CreateProcess() 사이의 차이점
2. ShellEcecute()와 ShellExecuteEx()가 다른 함수보다 우수한점
3. 동사들(Verb), 문서들 그리고 정책들(Policy)
4. 훅킹을 사용하여 프로세스 실행을 내 마음대로

그리고 다음과 같은 몇가지 예제 코드를 살펴볼 것이다.
1. 디폴트 브라우져 감지법
2. 프로그램을 실행시키고 종료를 기다리는법
3. 어떤 파일에 대한 등록정보 대화상자를 나타내는법
4. 찾기 대화상자를 화면에 출력하는 법
5. 사용자가 특정 폴더를 액세스하지 못하게 하거나, 다른 특정 어플리케이션을 실행하지 못하게 막는법

=====================================================

1. WinExec()에서 CreateProcess()로...

UINT WinExec(LPCSTR lpCmdLine, UINT uCmdShow);
이 함수는 Windows 3.x에서는 외부 프로그램을 실행시키는 유일한 방법이었다. 그리고 가장 간단한 사용법을 가지기도 한다.
하지만 단점이라 불리울 수 있는 것이 일단 실행을 시켜 놓으면 실행이 되는지 에러가 났는지, 종료 되었는지 전혀 알수가 없다는 것이다.

다음은 CreateProcess()의 프로토 타입이다.
BOOL CreateProcess(
LPCTSTR lpApplicationName, // 실행파일 모듈의 이름에 대한 포인터
LPTSTR lpCommandLine, // 커맨드 문자열에 대한 포인터
LPSECURITY_ATTRIBUTES lpPA, // 프로세스 보안 속성 포인터
LPSECURITY_ATTRIBUTES lpTA, // 스레드 보안속성 포인터
BOOL bInheritHandles, // 핸들 상속 여부 플래그
DWORD dwCreationFlags, // 생성 플래그
LPVOID lpEnvironment, // 환경 블록에 대한 포인터
LPCTSTR lpCurrentDirectory, // 현재 디렉토리
LPSTARTUPINFO lpStartupInfo, // STARTUPINFO 포인터
LPPROCESS_INFORMATION lpPI // PROCESS_INFORMATION 포인터
);

보시다 시피 여기에는 많은 파라미터들이 있다 하지만.. 대부분의 내용이 MSDN에 잘 문서화가 되어 있으므로 그렇게 어렵다거나 하지는 않다.
일단 가장 간단한 호출을 한번 살펴보자.

STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(STARTUPINFO));

CreateProcess(NULL, szPrgName, NULL, NULL, TRUE, NORMAL_PRIORITY_CLSS, NULL, NULL, &si, &pi);

WinExec보다는 복잡하지만 여러가지 부가적인 정보를 줄 수도 있고 받을 수도 있으므로 상대적인 저비용이다.

만약 위의 프로그램을 실행시키고 종료하기를 기다린다고 하면..

BOOL b = CreateProcess(............);
if(!b)
return FALSE;

WaitForSingleObject(pi.hProcess, INFINITE);
return TRUE;

정말 간단하지 않는가? ^^;
위의 결과를 외견상으로 보면 WinExec의 문제점들의 CreateProcess() 함수로써 모두 해결했다는 생각을 할 수도 있겠지만 현재의 문서라는 개념은 좀더 일반화 되었다. 위에서 사용된 실행가능한 프로그램(exe, com ...etc)등은 문서의 한가지 유형일 뿐이다.


2. ShellExecute()와 ShellExecuteEx()가 다른 함수보다 우수한점

HINSTANCE ShellExecute(
HWND hwnd, // 부모 윈도우 핸들
LPCTSTR lpVerb, // 동사 혹은 작업
LPCTSTR lpFile, // 실행 대상 문서
LPCTSTR lpParameters, // 컴맨드 인자
LPCTSTR lpDirectory, // 현재 디렉토리
INT nShowCmd // 보여주기 옵션
);

일단 위의 함수를 살펴보면 CreateProcess() 함수보다 기능이 많이 떨어지는 것 처럼 보이지만 이 함수의 진정한 의미는 동사 연결이라는 점이다.
보통 우리가 말하는 [연결 프로그램]을 지칭한다.

위에서 [동사 혹은 작업] 부분의 LPCTSTR lpVerb 에 사용될 수 잇는 것은데 대한 나열이다.
===============================================
열기(open) - 프로그램/문서/폴더
탐색(explore) - 폴더
인쇄(print) - 문서
~~로 인쇄(printto) - 문서
찾기(find) - 폴더

------> 먼저 열기(open)에 대하여 살펴보자.

ShellExcute(hwnd, "open", "c:\\prog.exe", "/nologo", "d:\\", SW_SHOW);

ShellExcute(hwnd, "open", "c:\\file.txt", NULL, NULL, SW_SHOW);

만약 txt확장자를 가진 파일에 대한 연결이 존재하지 않으면 우리가 많이 보던 연결프로그램 대화상자가 나타날 것이다.

------> 탐색 작업

탐색 작업은 폴더에 대해서만 가능하고 open 인경우와 약간의 차이를 나타낸다.
open로 동사를 주면 pane이 하나로 된 창이 뜨고, explore로 주면 pane가 2개인 탐색기다 뜬다.

ShellExcute(hwnd, "expolre", "c:\\", NULL, NULL, SW_SHOW);

------> 인쇄 작업

인쇄작업은 문서를 인쇄하기 위한 것이지만, 지정된 문서를 인쇄할 수 있는 명령어 라인과 프로그램을 정확히 알나내기 위해 레지스트리에 저장된 정보에 의존한다.

ShellExcute(hwnd, "print", "c:\\file.txt", NULL, NULL, SW_SHOW);

이 함수는 텍스트 파일을 처리하기 위해 등록된 프로그램을 찾고, 그 프로그램에 인쇄를 위한 명령이 있는지 검사한다. 정상적이라면 이 프로그램은 notepad.exe가 될 것이고, 그 명령어 라인은 다음과 같다.

notepad.exe /p

디폴트 프린터로의 인쇄는 위에서 처럼 간단하게 사용이 가능하지만 만약 여러개의 프린터가 있거나 출력 포트를 설정하고 싶다면 printto를 사용해야 한다.

만약 printto가 문서에서 지원이 된다면 등록된 명령이 실행될것이고 그렇지 못하다면..
경고창이 뜨면서 디폴트 프린터로 출력할 것이지를 묻는다.

------> 찾기 작업

지정된 경로를 루트로 찾기 창이 생성된다.
예제는 생략한다. ^^;


그렇다면 파일을 열기 위해서 혹은 그 파일과 연결된 실행 프로그램은 어떻게 구할 수 있는가?
의외로 쉽게 구할 수 있다. SDK에서 API를 제공하니까 ^^;

HINSTANCE FindExecuteable(
LPCTSTR lpFile, // 알아볼 파일
LPCTSTR lpDir, // 경로
LPTSTR lpResult) // 찾은 결과값

하지만 위 함수에는 치명적인 결함이 있다.
1. 보통 연결 프로그램은 확장자를 기준으로 검색되지만 이 함수는 항상 파일이 존재하여야만 결과를 리턴한다.
2. 경로에 공백이 있어도 않된다.
3. 리턴하는 결과에도 공백이 있으면 잘린다.

한마디로 엉터리에 가까운 API라 말할 수 있다.
이렇듯 이 함수는 규칙없이 긴 이름을 가진 파일을 염두에 두지 않고 설계되었기 때문에 생기는 문제인데..
MS에서 알고 있지만 절대 고치지 않는다..
Windows 이후로 긴 이름의 파일을 지원하지만..
MS Windows에서 시스템 명령어 중에 8.3포멧을 지키지 않는 명령어는 아직까지도 존재하지 않는다.

이 문제를 바로잡기 위한 FindExecutableEx를 만들어보자.
HINSTANCE FindExecutableEx(... 인자는 동일하다 ...)
{
TCHAR drive[_MAX_DRIVE];
TCHAR dir[_MAX_DIR];
TCHAR dir1[_MAX_DIR];
TCHAR file[_MAX_FILE];
TCHAR ext[_MAX_EXT];

HINSTANCE hi = FindExecutable(file, dir, result);
result[lstrlen(result)] = 32;

_splitpath(result, deive, dir, file, ext);

LPTSTR p = strchr(dir, ':');
if(p != NULL)
{
--p;
dir[p-dir] = 0;
_splitpath(dir, NULL, dir1, file, ext);
p = strchr(ext, 32);
ext[p-ext] = 0;
_makepath(result, drive, dir1, file, ext);
}
return hi;
}

//
1. 디폴트 브라우저 감지하기
void GetDefaultBrowser(LPTSTR szBrowerName)
{
HFILE h = lcreate("dummy.htm", 0);
_lclose(h);

FindExecutable("dummy.htm", NULL, szBrowserName);
DeleteFile("dummy.htm");
}


2. URL로 연결
ShellExecute(NULL, NULL, "http://lop.com", NULL, NULL, SW_SHOW);

3. e-mail 보내기
ShellExecute(NULL, NULL, "mailto:crowback@a.co.kr", NULL, NULL, SW_SHOW);

4. 문서 인쇄
ShellExecute(NULL, "print", 문서명, NULL, NULL, SW_SHOW);

5. 파일과 폴더 찾기
ShellExecute(NULL, "find", 문서명, NULL, NULL, SW_SHOW);

자자...위에는 간단한 예문을 몇가지 들어본 것이다.
그럼 본격적으로 다음 단계를 진행해보자.

ShellExcute() vs CreateProcess()

여기서의 요점은 어느것이 더 좋은가가 아니라 어느것이 프로세스를 생성할 경우 더 유용한가를 논할 것이다.
고려해야할 첫번째 사항으로 ShellExecute()는 내부적으로 CreateProcess를 호출한다는 것과, 따라서 ShellExecute는 CreateProcess를 위한 더 작고 사용하기 간단한 wrapper이다. 다시 말해서, 문서들을 열고 인쇄하기에는 ShellExecute가 훨씬 더 융통성이 있으며, 문서에 대해 할 수 있는 다른 작업도 마찬가지이다.

ShellExecute()를 사용해서 프로그램을 실행하면 좋은이유

ShellExecute를 사용하는 쪽에 무게를 두는 이유는 MS의 지침이 MS의 새로운 LOGO에 대한 요구사항으로 방대한 안을 내놓았는데, Win98, WinNT 혹은 그이상의 운영체제에 사용되는 MS 어플리케이션 로고를 붙이려면 몇가지 ShellExecute를 사용해서 외부 어플리케이션을 실행시키도록 권장하고 있다. 그렇게 하면 시스템 관리자가 채택한 제한 정책이 모두 확실하고도 주의 깊게 검사될것이기 때문이다. 시스템 관리자는 어플리케이션이 Windows에서 시작될 수 있는지, 또는 없는지를 결정하게 한다. ShellExecute는 이 블랙리스트를 고려한 것이지만 CreateProcess는 그렇지가 않다.

ShellExecuteEx()로의 확장
정책적인 지원에도 불구하고 ShellExecute()는 여러가지 제한점을 많이 가지고 있다. 그 치명적인 단점의 하나가 새로 생성된 프로세스를 반환하지 않는다는 것이다. 다시 말해 프로그램이 실행되어서 종료됫는지, 아직도 실행중인지, 내 프로그램이 방금 실행한 프로그램을 기다릴 수 있는 방법이 없다는 것이다. 하지만 쉘버전 4.0에서 새로운 함수가 소개되었다. 바로 ShellExecuteEx() 이다.
이 함수는 프로토타입처럼 간결하고 많은 플래그를 지원하고 무엇보다도 PIDL을 지원할 수 있도록 ShellExecute()를 확장하여 놓았다는 점이다.

BOOL ShellExecuteEx(LPSHELLEXECUTEINFO lpExexInfo);

LPSHELLEXECUTEINFO 구조는 다음과 같다.
typedef struct _SHELLEXECUTEINFOA
{
DWORD cbSize;
ULONG fMask;
HWND hwnd;
LPCSTR lpVerb;
LPCSTR lpFile;
LPCSTR lpParameters;
LPCSTR lpDirectory;
int nShow;
HINSTANCE hInstApp;
// Optional fields
LPVOID lpIDList;
LPCSTR lpClass;
HKEY hkeyClass;
DWORD dwHotKey;
union {
HANDLE hIcon;
HANDLE hMonitor;
};
HANDLE hProcess;
} SHELLEXECUTEINFO, FAR *LPSHELLEXECUTEINFO;

이 구조를 사용하기 전에 이 구조체를 0으로 체구고 cbSize값에다가 실제 길이를 넣어두면 된다.

SHELLEXECUTEINFO si;
ZeroMemory(&si, sizeof(SHELLEXECUTEINFO));
si.cbSize(sizeof(SHELLEXECUTEINFO));

다음에서 ShellExecuteEx()를 실행하는 가장 간단한 방법을 살펴보자.

SHELLEXECUTEINFO si;
ZeroMemory(&si, sizeof(SHELLEXECUTEINFO));
si.cbSize(sizeof(SHELLEXECUTEINFO));

si.lpFile = __TEXT("explorer.exe");
si.nShow = SW_SHOW;
si.lpVerb = __TEXT("open");
ShellExecuteEx(&si);

다음에서는 부가적인 기능으로 PIDL을 이용하여 호출하는 것을 살펴보자.

LPITEMIDLIST pidl;
SHGetSpecialFolderLocation(NULL, CSIDL_PRINTER, &pidl);

SHELLEXECUTEINFO si;
ZeroMemory(&si, sizeof(SHELLEXECUTEINFO));
si.cbSize(sizeof(SHELLEXECUTEINFO));

si.nShow = SW_SHOW;
si.lpIDList = pidl;
si.fMask = SEE_MASK_INVOKEIDLIST;
si.lpVerb = __TEXT("open");
ShellExecuteEx(&si);

만약 fMask에 SEE_MASK_NOCLOSEPROCESS를 포함하였다면
hProcesss 멤버를 통하여 새로생긴 프로세스의 핸들을 반환 받을 수 있다.

WaitForSingoeObject(si.hProcess, INFINITE);

자 여기까지 기본적인 ShellExccute()와 그 확장 ShellExecuteEx()의 대략적인 용법과 사용예에 대하여 살펴보았다.

여기서 좀더 색다를 점을 강조해 보면 ShellExecuteEx()는 정적인 동사 뿐만 아니라 동적인 동사도 불러낼 수 있다는 점이다.
이것이 움직이는 방법은 다음과 같다. 만일 ShellEcecuteEx()가 정적 동사 목록에서 찾는 동사를 찾을 수 없으면 주어지 ㄴ파일에 대한 컨텍스트 메뉴를 뒤진다. 이런 탐색 과정은 IContextMenu 인터페이스에 대한 포인터를 낳는다. 그리고나서, 이 인터페이스에 노축될 함수를 통해 동적인 동사를 불러낸다.

그 결과로, 파일의 [등록정보] 대화살자를 쉽게 화면에 출력할 수 있게 된다. 이 대화상자는 파일 위에서 오른쪽 마우스로 등록정보를 클릭한것과 같은 대화상자를 출력한다.

void ShowFileProperties(LPCTSTR szPathName)
{
SHELLECECUTEINFO sei;
ZeroMemory(&sei, sixeof(SHELLECECUTEINFO));
sei.cbSize = sixeof(SHELLECECUTEINFO);

sei.lpFile = szPathName;
sei.nShow = SW_SHOW;
sei.fMask = SEE_MASK_INVOKEIDLIST;
sei.lpVerb = __T("properties");
ShellExecuteEx(&sei);
}

출처 : http://kwangdae.tistory.com/48

Posted by pkss
,

[Socket] send

MFC 2012. 1. 30. 18:31

send

send 함수는 접속되어 있는 상대방 소켓으로 데이터를 보내는 함수입니다.

int send (
SOCKET
s,
const char FAR *
buf,
int
len,
int
flags
);

Parameters
s
[입력] 접속되어 있는 소켓의 기술자(descriptor)를 기술합니다.

buf
[입력] 전송하려는 데이터를 가지고 있는 버퍼

len
[입력]
buf 안에있는 데이터의 길이

flags
[입력] 함수의 호출이 어떤일을 할지 나타내는 플래그 입니다.

Remarks

send는 접속된 소켓에서 데이터를 접속된 상대방으로 전송하는데 사용되는 함수입니다. 메시지 지향 소켓(message-oriented sockets)에서 최대 패킷크기(getsockopt 함수로 SO_MAX_MSG_SIZE 옵션의 값을 얻어내서 최대 크기를 구할 수 있습니다.)를 초과하지 않도록 주의 해야 합니다. 만약 데이터가 전송되기에 너무 크다면, 데이터는 전송되지 않고, WSAEMSGSIZE 에러코드를 발생합니다.

send 함수의 성공적인 종료가 성공적인 데이터의 전송을 의미하지는 않는다는 점을 명심하세요.

전송 시스템에 사용 가능한 버퍼가 없다면, 소켓이 넌블록킹(비동기)모드일 경우를 제외하고 send는 블록합니다. 비동기 스트림 소켓(nonblocking stream oriented sockets)에서 전송된 바이트의 크기는 1부터 요청된 데이터의 길이 사이의 수가 될 수 있습니다. select, WSAAsyncSelect, WSAEventSelect 함수는 한번 데이터를 전송하고 언제 다른 데이터를 보낼 수 있는지를 결정하는데 사용됩니다. 데이터는 아무때나 보낼 수 있는게 아닙니다. 물론 비동기 소켓에서 연속된 send를 사용할 수 있습니다. 하지만, 안정적인 데이터 송수신을 기대 할 수 없죠. 그렇기 때문에 소켓은 데이터를 전송 할 수 있는 상태가 되었을 때 비로소 데이터를 전송해야 합니다.

len 매개변수를 0으로 해서 send 함수를 호출하는 것은 허용되고, 성공적으로 처리됩니다. 이러한 경우에는 send 함수는 0을 리턴합니다. 메시지 지향 소켓(message-oriented sockets)일경우는 0 길이의 데이터그램이 전송되어 집니다.

flag 매개변수는 소켓에 대해 명시된 옵션 이상의 함수동작에 영향을 미치기 위해서 사용될 수 있습니다. 함수의 의미체계는 소켓옵션 그리고, flag 매개변수에 의해서 결정되어 집니다. flag 매개변수를 이용한 방법의 경우 아래의 값을 OR 비트연산을 취해서 구성되어 집니다.

Value Meaning
MSG_DONTROUTE

데이터는 라우팅 될 수 없음을 나타냅니다. 윈도우즈 소켓 시스템은

대응하는 소켓옵션과 마찬가지로 이 값을 무시 할 수 있습니다.

MSG_OOB

데이터가 out-of-band 데이터로서 전송될 수 있음을 나타냅니다.

이 플래그는 스트림 소켓과만 사용됩니다.

Return Values

에러가 발생하지 않는다면, send 함수는 전송된 총 데이터 크기를 반환합니다. 비동기 소켓의 경우 len 매개변수로 건넨 수치보다 작을 수 있습니다. 에러가 발생한 경우는 SOCKET_ERROR를 반환하고, WSAGetLastError를 이용해서 특정한 에러코드를 얻어낼 수 있습니다.

Error Codes

WSANOTINITIALISED

이 함수를 사용하기 전에 성공적인 WSAStartup 함수의 호출이

없었습니다.

WSAENETDOWN 네트웍 서브 시스템에 에러가 발생했습니다.
WSAEACCES

요청된 주소가 브로트캐스트(broadcast) 주소인데, 적절한

플래그가 셋팅되어 있지 않습니다. 브로드캐스트 어드레스의

사용을 허용하기 위해 SO_BROADCAST 매개변수를 가지고,

setsockopt 함수를 호출 해야 합니다.

WSAEINTR

블록킹 호출이 WSACancelBlockingCall 함수에서

취소되었습니다.

WSAEINPROGRESS

블럭킹 윈속 v1.1 이 현재 진행 중이거나, 서비스 프로바이더가

콜백 함수를 여전히 처리하고 있습니다.

WSAEFAULT buf 매개변수가 제대로 된 형태가 아닙니다.
WSAENETRESET 연산이 진행되고 있는 도중 접속이 끊겨버렸습니다.
WSAENOBUFS 전송하기 위해 사용할 수 있는 버퍼 공간이 없습니다.
WSAENOTCONN 소켓이 접속된 상태가 아닙니다.
WSAENOTSOCK 기술자(descriptor)가 소켓 기술자가 아닙니다.
WSAEOPNOTSUPP

MSG_OOB 가 명시되었지만, 소켓은 SOCK_STREAM 과 같은

형태의 스트림 형태가 아닙니다.

WSAESHUTDOWN 소켓이 셧다운 되었습니다.
WSAEWOULDBLOCK

소켓이 넌블록킹(비동기)로 마킹되어 있고, 수신 연산이 블록킹

상태입니다.

WSAEMSGSIZE

소켓이 메시지 지향형(message oriented)이고, 메시지의

크기가 허용할 수 있는 최대 크기 보다 큽니다.

WSAEHOSTUNREACH

네트웍 시스템 장애 등에 의해서 원격호스트까지 도달 할 수

없습니다.

WSAEINVAL

소켓이 bind 함수에 의해서 바인드 되지 않았거나, 알 수 없는

플래그가 사용되었거나, SO_OOBINLINE 옵션을 가능하게 한

상태 에서 MSG_OOB 플래그가 소켓에 대해서 명시되었습니다.

또는 len 매개변수가 0 이거나 0보다 작습니다.

WSAECONNABORTED

가상 연결 회로망이 타임아웃이나 다른 실패 때문에 끊어져

버렸습니다.

WSAECONNRESET

가상 회로망이 원격지에서 "hard"나 "abortive" 종료를 수행해서

리셋되었습니다.

WSAETIMEDOUT

접속이 네트웍 실패나 상대방 시스템의 응답 실패로 인하여

드랍 되어 버렸습니다.

QuickInfo

Windows NT : 사용가능
Windows : 사용가능
Windows CE : 버젼 1.0 그리고 그이후의 버젼에서 사용가능
Header :
Win16/32 : winsock.h
Win32-II : winsock2.h
Import Library :
Win16 : winsock.lib
Win32 : wsock32.lib
Win32-II : ws2_32.lib

See Also

overview, recvfrom, select, sendto, socket, WSAAsyncSelect, WSAEventSelect

출처 : DEVPIA 곽용진님 style APIs

출처 : http://blog.naver.com/sojuchoigo?Redirect=Log&logNo=120021311620

Posted by pkss
,