serv_addr.sin_addr.s_addr = INADDR_LOOPBACK

 

 

s_addr 에 값을 세팅할때 INADDR_LOOPBACK 플래그로 세팅하면 로컬에서만 접속됨.

#define MAKEBYTE(hi, lo)   ((unsigned char)0xF0 & (hi << 4)) | ((unsigned char)0x0F & (lo))
#define HIBYTE(w)    ((unsigned char)0xF0 & w) >> 4
#define LOBYTE(w)    ((unsigned char)0x0F & w);

 

 

unsigned char cSum = 0;

 //cSum = sTemp[0] | sTemp[1] << 4;
 cSum = MAKEBYTE(sTemp[0], sTemp[1]);

 sTemp[2] = HIBYTE(cSum);
 sTemp[3] = LOBYTE(cSum);

 

 

4비트 단위로 쪼개면 각각 0~15 값(2의 4승) 까지만 사용 가능

 

 

 

POSIX Timer 예제



#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;


#define SIGTIMER (SIGRTMAX)
#define ONESHOTTIMER (SIGRTMAX-1)

timer_t SetTimer(int signo, int sec, int mode);
void SignalHandler(int signo, siginfo_t * info, void *context);
timer_t timerid,oneshotTimer;

int main()
{
	struct sigaction sigact;

	sigemptyset(&sigact.sa_mask);
	sigact.sa_flags = SA_SIGINFO;
	sigact.sa_sigaction = SignalHandler;

	// Set up sigaction to catch signal
	if (sigaction(SIGTIMER, &sigact, NULL) == -1) {
		perror("sigaction failed");
		return -1;
	}
	// Set up sigaction to catch signal
	if (sigaction(ONESHOTTIMER, &sigact, NULL) == -1) {
		perror("sigaction failed");
		return -1;
	}
	// Establish a handler to catch CTRL+C and use it for exiting
	sigaction(SIGINT, &sigact, NULL);

	timerid = SetTimer(SIGTIMER, 500, 1);
	oneshotTimer = SetTimer(ONESHOTTIMER, 5000, 0);
	while(1);
	return 0;
}
timer_t SetTimer(int signo, int sec, int mode)
{
	struct sigevent sigev;
	timer_t timerid;
	struct itimerspec itval;
	struct itimerspec oitval;

	// Create the POSIX timer to generate signo
	sigev.sigev_notify = SIGEV_SIGNAL;
	sigev.sigev_signo = signo;
	sigev.sigev_value.sival_ptr = &timerid;

	if (timer_create(CLOCK_REALTIME, &sigev, &timerid) == 0) {
		itval.it_value.tv_sec = sec / 1000;
		itval.it_value.tv_nsec = (long)(sec % 1000) * (1000000L);

		if (mode == 1) {
			itval.it_interval.tv_sec = itval.it_value.tv_sec;
			itval.it_interval.tv_nsec = itval.it_value.tv_nsec;
		} else {
			itval.it_interval.tv_sec = 0;
			itval.it_interval.tv_nsec = 0;
		}

		if (timer_settime(timerid, 0, &itval, &oitval) != 0) {
			perror("time_settime error!");
		}
	} else {
		perror("timer_create error!");
		return (timer_t)-1;
	}
	return timerid;
}
void SignalHandler(int signo, siginfo_t * info, void *context)
{
	if (signo == SIGTIMER) {
		puts("Periodic timer");
	}
	else if (signo == ONESHOTTIMER) {
		puts("One-short timer");
	}
	else if (signo == SIGINT) {
		timer_delete(oneshotTimer);
		timer_delete(timerid);
		perror("Ctrl + C cached!\n");
		exit(1);
	}
}


c 코딩으로 만든 내 네트워크 상의 모든 컴퓨터 목록 또는 Local Network 목록을 가져오고

 

그 이름을 가지고 IP 주소까지 얻어오는 코드이다.


#ifndef UNICODE 
#define UNICODE 
#endif 
#pragma comment(lib, "netapi32.lib") 
#include 
#include 
#include 
#include 
#include 
#pragma comment(lib, "ws2_32.lib") // 해당 컴퓨터의 플랫폼 이름 
char* PrintPlatform(DWORD dwPlatformId) 
{ 
	switch(dwPlatformId) 
	{ 
	case PLATFORM_ID_DOS:				return "The MS-DOS platform";
	case PLATFORM_ID_OS2:				return "The OS/2 platform";
	case PLATFORM_ID_NT:				return "The Windows NT platform";
	case PLATFORM_ID_OSF:				return "The OSF lpatform";
	case PLATFORM_ID_VMS:				return "The VMS platform";
	default:							return "Unknown Platform";
	} 
} 

// MSDN 을 참조하였으나 일치 하는 코드가 없는것 같다.
char* Printsv101Type(DWORD dwType) 
{ 
	switch(dwType) 
	{ 
	case SV_TYPE_WORKSTATION:			return "A workstation.";
	case SV_TYPE_SERVER:				return "A server.";
	case SV_TYPE_SQLSERVER:				return "A server running with Microsoft SQL Server.";
	case SV_TYPE_DOMAIN_CTRL:			return "A primary domain controller.";
	case SV_TYPE_DOMAIN_BAKCTRL:		return "A backup domain controller.";
	case SV_TYPE_TIME_SOURCE:			return "A server running the Timesource service.";
	case SV_TYPE_AFP:					return "A server running the Apple Filing Protocol (AFP) file service.";
	case SV_TYPE_NOVELL:				return "A Novell server.";
	case SV_TYPE_DOMAIN_MEMBER:			return "A LAN Manager 2.x domain member.";
	case SV_TYPE_PRINTQ_SERVER:			return "A server that shares a print queue.";
	case SV_TYPE_DIALIN_SERVER:			return "A server that runs a dial-in service.";
	case SV_TYPE_XENIX_SERVER:			return "A Xenix or Unix server.";
	case SV_TYPE_NT:					return "A workstation or server.";
	case SV_TYPE_WFW:					return "A computer that runs Windows for Workgroups.";
	case SV_TYPE_SERVER_MFPN:			return "A server that runs the Microsoft File and Print for NetWare service.";
	case SV_TYPE_SERVER_NT:				return "Any server that is not a domain controller.";
	case SV_TYPE_POTENTIAL_BROWSER:		return "A computer that can run the browser service.";
	case SV_TYPE_BACKUP_BROWSER:		return "A server running a browser service as backup.";
	case SV_TYPE_MASTER_BROWSER:		return "A server running the master browser service.";
	case SV_TYPE_DOMAIN_MASTER:			return "A server running the domain master browser.";
	case SV_TYPE_SERVER_OSF:			return "A computer that runs OSF.";
	case SV_TYPE_SERVER_VMS:			return "A computer that runs VMS.";
	case SV_TYPE_WINDOWS:				return "A computer that runs Windows.";
	case SV_TYPE_DFS:					return "A server that is the root of a DFS tree.";
	case SV_TYPE_CLUSTER_NT:			return "A server cluster available in the domain.";
	case SV_TYPE_TERMINALSERVER:		return "A server that runs the Terminal Server service.";
	case SV_TYPE_CLUSTER_VS_NT:			return "Cluster virtual servers available in the domain.";
	case SV_TYPE_DCE:					return "A server that runs the DCE Directory and Security Services or equivalent.";
	case SV_TYPE_ALTERNATE_XPORT:		return "A server that is returned by an alternate transport.";
	case SV_TYPE_LOCAL_LIST_ONLY:		return "A server that is maintained by the browser.";
	case SV_TYPE_DOMAIN_ENUM:			return "A primary domain.";
	default:							return "Unknown Type";
	} 
} // Write : Acidpop 


void PrintHostIP(wchar_t* szName) 
{ 
	char** pptr = NULL;
	struct hostent *host_entry = NULL;
	char lServerName[256] = "";
	char szIpAddr[256] = "";
	struct in_addr addr; 

	// Acidpop, wchar_t 를 char 형태로 바꾼다. 
	WideCharToMultiByte(CP_ACP, 0, szName, -1, lServerName, 255, NULL, NULL); 

	// struct hostent 를 얻어온다. 
	host_entry = gethostbyname(lServerName); 

	if( host_entry != NULL) 
	{ 
		// 해당 컴퓨터가 n개의 랜카드를 가질 수 있으므로.. 
		for(int i=0 ; host_entry->h_addr_list[i] ; i++) 
		{ 
			// struct in_addr type을 복사하여 IP 주소로 변환한다. 
			memcpy(&addr, host_entry->h_addr_list[i], sizeof(struct in_addr));
			printf("\tIP: %s\n", inet_ntoa(addr));
		} 
	} 
} 


int wmain(int argc, wchar_t * argv[]) 
{
	LPSERVER_INFO_101 pBuf = NULL;
	LPSERVER_INFO_101 pTmpBuf;
	DWORD dwLevel = 101;
	DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH;
	DWORD dwEntriesRead = 0;
	DWORD dwTotalEntries = 0;
	DWORD dwTotalCount = 0;
	DWORD dwServerType = SV_TYPE_SERVER;
	// all servers 
	DWORD dwResumeHandle = 0;
	NET_API_STATUS nStatus;
	LPWSTR pszServerName = NULL;
	LPWSTR pszDomainName = NULL;
	DWORD i;
	if (argc > 2) 
	{ 
		fwprintf(stderr, L"Usage: %s [DomainName]\n", argv[0]);
		exit(1);
	} // The request is not for the primary domain. // 
	if (argc == 2) 
		pszDomainName = argv[1];
	WSAData wsaData;
	if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) 
	{
		return 255;
	} // 
	// Call the NetServerEnum function to retrieve information 


	// for all servers, specifying information level 101. 
	nStatus = NetServerEnum(pszServerName, dwLevel, (LPBYTE *) & pBuf, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries, dwServerType, pszDomainName, &dwResumeHandle);

	// 
	// If the call succeeds, 
	if ((nStatus == NERR_Success) || (nStatus == ERROR_MORE_DATA)) 
	{ 
		if ((pTmpBuf = pBuf) != NULL) 
		{ 
			// 
			// Loop through the entries and 
			// print the data for all server types. 
			for (i = 0;i < dwEntriesRead; i++) 
			{ 
				assert(pTmpBuf != NULL);
				if (pTmpBuf == NULL) 
				{ 
					fprintf(stderr, "An access violation has occurred\n");
					break;
				} 
				printf("\tPlatform: %s(%d)\n", PrintPlatform(pTmpBuf->sv101_platform_id), pTmpBuf->sv101_platform_id );
				wprintf(L"\tName: %s\n", pTmpBuf->sv101_name);
				printf("\tVersion: %d.%d\n", pTmpBuf->sv101_version_major, pTmpBuf->sv101_version_minor);
				printf("\tType: %s(%d)\n", Printsv101Type(pTmpBuf->sv101_type), pTmpBuf->sv101_type);
				PrintHostIP(pTmpBuf->sv101_name);

				// Check to see if the server is a domain controller;
				// if so, identify it as a PDC or a BDC. 
				if (pTmpBuf->sv101_type & SV_TYPE_DOMAIN_CTRL) 
					wprintf(L" (PDC)");
				else if (pTmpBuf->sv101_type & SV_TYPE_DOMAIN_BAKCTRL) 
					wprintf(L" (BDC)"); printf("\n"); 


				// Also print the comment associated with the server. 
				wprintf(L"\tComment: %s\n\n", pTmpBuf->sv101_comment); 
				pTmpBuf++; 
				dwTotalCount++; 
			} 

			// Display a warning if all available entries were 
			// not enumerated, print the number actually 
			// enumerated, and the total number available. 
			if (nStatus == ERROR_MORE_DATA) 
			{ 
				fprintf(stderr, "\nMore entries available!!!\n"); fprintf(stderr, "Total entries: %d", dwTotalEntries); 
			} 

			printf("\nEntries enumerated: %d\n", dwTotalCount); 
		} 
		else 
		{ 
			printf("No servers were found\n"); 
			printf("The buffer (bufptr) returned was NULL\n"); 
			printf(" entriesread: %d\n", dwEntriesRead); 
			printf(" totalentries: %d\n", dwEntriesRead); 
		} 
	} 
	else 
		fprintf(stderr, "NetServerEnum failed with error: %d\n", nStatus); 

	// Free the allocated buffer. 
	if (pBuf != NULL) 
		NetApiBufferFree(pBuf); 


	WSACleanup(); 

	return 0;
} 

코드 참조는 MSDN 의 샘플코드를 토대로 IP 부분만 추가한 소스인다.

 

참고 MSDN : ( http://msdn.microsoft.com/en-us/library/windows/desktop/aa370623(v=vs.85).aspx )

long GetLastNLine(int nLastLine)
{
	int nLineCount = 0;
	char ch = '\0';
	TCHAR szBuf[8192] = _T("");
	int nResult = 0;
	long lCurPos = 0;

	FILE* fp = fopen("20121119_10.log", "r");

	fseek(fp, -1, SEEK_END);

	//fseek(fp, -1, SEEK_CUR);

	while( 1 )
	{
		ch = (char)fgetc(fp);
		if( ch == '\n' )
		{
			nLineCount++;

			if( nLineCount >= nLastLine )
			{
				break;
			}

			 fseek(fp, -1, SEEK_CUR);
		}

		nResult = fseek(fp, -2, SEEK_CUR);

		if( nResult != 0 )	// File 의 시작 위치 까지 왔을 때에는 break;
		{
			fseek(fp, 0, SEEK_SET);
			break;
		}
	}

	while( _fgetts(szBuf, sizeof(szBuf), fp) )
	{
		_tprintf(_T("%s\n"), szBuf);
	}

	lCurPos = ftell(fp);

	fclose(fp);

	return lCurPos;
}




Text 파일을 처음부터 읽는게 아닌 마지막에서 n 줄 부터 출력하는 예제

thread Class 사용 방법

 

Visual Studio 2012 에서는 이번 C++ 11 표준에서 thread 부분까지 적용이 되어

 

다음과 같이 Class 의 멤버 함수를 Thread 로 돌릴 수 있다.

#include 
#include 
#include 
#include 

using namespace std;


class Test
{
public:
	Test()
	{
		m_nNum = 0;
	}
	virtual ~Test()
	{
		printf("~Test\n");
	};
public:
	void ThreadFunc()
	{
		while(1)
		{
			printf("Num1 : %d\n", m_nNum);
			Sleep(1000);
			m_nNum++;

			if(m_nNum == 10)	break;
		}
	}

	void operator() ()
	{
		printf("Exit Thread");
	}
	void AddNum()
	{
		m_nNum++;
		printf("Call AddNum Func\n");
	}

private:
	int m_nNum;
};

int main()
{
	Test t;	
	thread th(&Test::ThreadFunc, &t);
	
	Sleep(1000);	
	t.AddNum();
	th.join();

	return 0;
}

Visual Studio 2012 가 있다면 한번 컴파일 해서 실행 시켜보면 될듯..?

Elevate.h
// Elevate.h: interface for the CElevate class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_ELEVATE_H__E7B50ED2_9C9D_4C00_93E9_C9547465DEFA__INCLUDED_)
#define AFX_ELEVATE_H__E7B50ED2_9C9D_4C00_93E9_C9547465DEFA__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

// Windows Vista 이상 OS 에서 관리자 권한 상승을 위한 Class
// 제작 : acidpop.tistory.com
// 날짜 : 2012/02/28

#include <shellapi.h>
#include <shlobj.h>


typedef struct _TOKEN_ELEVATION {
    DWORD TokenIsElevated;
} TOKEN_ELEVATION, *PTOKEN_ELEVATION;

#ifndef CSIDL_PROGRAM_FILES
#define CSIDL_PROGRAM_FILES 0x0026
#endif // CSIDL_PROGRAM_FILES


class CElevate  
{
public:
	CElevate();
	virtual ~CElevate();

public:
	// 특정 프로그램을 관리자 권한으로 실행 하기 위한 함수
	BOOL	ShellExecWithElevation(HWND hWnd, LPCTSTR lpPath, LPCTSTR lpParameters, LPCTSTR lpDirectory);

	// 자기 자신을 관리자 권한으로 다시 시작 하는 함수
	BOOL	SelfExecuteWithElevation();

	// 특정 Url 을 관리자 권한으로 Internet Explorer 를 실행 하는 함수
	BOOL	OpenUrlWithElevation(HWND hWnd, LPCTSTR lpUrl);

	// 권한 상승이 필요한지 여부, 1 - UAC 미지원 OS, 2 - 상태 정보 조회 불가, 3 - 권한 상승 필요, 4 - 권한 상승 되어 있음
	int		GetNeedElevate();

	// OS가 Vista 보다 상위 인지 여부
	BOOL	IsVistaOrHigher(void);
	
	// 권한 체크
	HRESULT IsElevated(BOOL *pElevated);

private:	
	// 관리자 권한으로 실행 하기 위한 가장 기초 함수,ShellExecWithElevation 를 사용하도록 권장
	BOOL	ShellExecWithVerb(HWND hWnd, LPCTSTR lpVerb, LPCTSTR lpPath, LPCTSTR lpParameters, LPCTSTR lpDirectory);
};

#endif // !defined(AFX_ELEVATE_H__E7B50ED2_9C9D_4C00_93E9_C9547465DEFA__INCLUDED_)



Elevate.cpp
// Elevate.cpp: implementation of the CElevate class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Elevate.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CElevate::CElevate()
{

}

CElevate::~CElevate()
{

}



int CElevate::GetNeedElevate()
{
	if (IsVistaOrHigher())
	{
		BOOL bResult = FALSE;
		
		if (SUCCEEDED(IsElevated(&bResult)))
		{
			if (bResult == TRUE)
				return 4; // 이미 Elevation이 완료됨
			else
				return 3; // Elevation이 필요함
		}
		else
			return 2; // 상태 정보를 조회할 수 없음
	}

	return 1; // UAC가 지원되지 않는 운영체제로 판단함
}

BOOL CElevate::IsVistaOrHigher(void)
{
	OSVERSIONINFO versionInfo;
	versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	
	if (GetVersionEx(&versionInfo) &&
		versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
		versionInfo.dwMajorVersion >= 6)
		return TRUE;
	else
		return FALSE;
}



HRESULT CElevate::IsElevated(BOOL *pElevated)
{
	HRESULT hResult = E_FAIL;
	HANDLE hToken = NULL;
	
	if (!IsVistaOrHigher())
		return hResult;
	
	if (!OpenProcessToken(
		GetCurrentProcess(),
		TOKEN_QUERY,
		&hToken))
		return hResult;
	
	TOKEN_ELEVATION te = { 0 };
	DWORD dwReturnLength = 0;
	const int TokenElevation = 20;
	
	if (GetTokenInformation(
		hToken,
		(TOKEN_INFORMATION_CLASS)TokenElevation,
		&te,
		sizeof(te),
		&dwReturnLength))
	{
		hResult = te.TokenIsElevated ? S_OK : S_FALSE;
		
		if (pElevated)
			*pElevated = (te.TokenIsElevated != 0);
	}
	
	CloseHandle(hToken);
	return hResult;
}



BOOL CElevate::ShellExecWithVerb(HWND hWnd, LPCTSTR lpVerb, LPCTSTR lpPath, LPCTSTR lpParameters, LPCTSTR lpDirectory)
{
	SHELLEXECUTEINFO executeInfo;
	memset(&executeInfo, 0, sizeof(executeInfo));
	
	executeInfo.cbSize = sizeof(SHELLEXECUTEINFO);
	executeInfo.fMask = 0;
	executeInfo.hwnd = hWnd;
	executeInfo.lpVerb = lpVerb;
	executeInfo.lpFile = lpPath;
	executeInfo.lpParameters = lpParameters;
	executeInfo.lpDirectory = lpDirectory;
	executeInfo.nShow = SW_NORMAL;
	
	return ShellExecuteEx(&executeInfo);
}



BOOL CElevate::ShellExecWithElevation(HWND hWnd, LPCTSTR lpPath, LPCTSTR lpParameters, LPCTSTR lpDirectory)
{
	return ShellExecWithVerb(hWnd, _T("runas"), lpPath, lpParameters, lpDirectory);
}

BOOL CElevate::SelfExecuteWithElevation()
{
	TCHAR pszPathName[_MAX_PATH] = "";

	TCHAR lpParameter[1024] = "";
	
	if(__argc > 1)
	{
		for(int i=1; i<__argc; i++)
		{			
			_tcscat(lpParameter, __argv[i]);
			_tcscat(lpParameter, " ");
		}
	}

	::GetModuleFileName(::AfxGetInstanceHandle(), pszPathName, _MAX_PATH);

	//PathRemoveFileSpec(pszPathName);
	return ShellExecWithElevation(NULL, pszPathName, lpParameter, _T(""));
}

BOOL CElevate::OpenUrlWithElevation(HWND hWnd, LPCTSTR lpUrl)
{
	_TCHAR lpBuffer[MAX_PATH + 1];
	
	if (!SHGetSpecialFolderPath(hWnd, lpBuffer, CSIDL_PROGRAM_FILES, 0))
		return FALSE;
	
	_tcscat(lpBuffer, _T("\\Internet Explorer\\iexplore.exe"));
	return ShellExecWithElevation(hWnd, lpBuffer, lpUrl, _T(""));
}


<SPAN id=tx_marker_caret></SPAN>



위 클래스를 이용하여 ShellExecWithElevation  함수를 이용하면 응용 프로그램도 관리자 권한으로 실행하도록

요청할 수 있다.


예전에 개발을 하다가 정말 이상한 현상을 발견해서 한참 고생한적이 있다.

rand 함수를 이용해 키 값을 만드는 모듈이었는데

분명 srand(time(NULL));  을 호출을 했는데도 불구하고

rand() 함수가 계속 똑같은 패턴으로 숫자를 만들어내는것이다.

아니 도데체 이게 뭔일인가 싶어서 디버깅도 해보고

1스텝씩 지나가봐도 srand 는 분명 호출을 하는데 rand 는 똑같은 숫자만 나오고...ㅠㅠ

며칠이 지나서 알게 된 사실

srand 는 프로세스 종속이 아닌 Thread 종속이다.

즉 Thread 별로 srand seed 값을 설정해야 한다는 점이다.

나는 main 함수쪽에서 srand 를 호출했으니 당연히 전역적으로 rand 가 바뀔꺼라 생각해서 만든 모듈이었는데..

즉 rand 함수를 사용하는 Thread 에서 초기에 srand 로 seed 값 설정을 해야 한다.

아직 Thread 를 다루지 않고 있는 사람도 알아 두면 좋을것 같아 블로그에 포스팅한다.



좀 더 자세히 설명되어 있는 블로그가 있어 링크를 참조하면 좋을듯

http://jacking.tistory.com/450

+ Recent posts