Hello World를 출력하는 소켓 프로그램의 구현[각주:1]

일반적으로 소켓 프로그램은 서비스를 요청하는 클라이언트측과 클라이언트로부터의 요청을 받아 서비스하는 서버측, 이렇게 두 곳에서 상주하는 프로그램으로 구성된다.





구현할 소켓 프로그램이 수행하는 기능을 정리하면 아래와 같다.

  1. 연결 요청

    • 클라이언트 프로그램은 소켓 API 함수를 호출하여 서버 프로그램에 연결.
  2. 문자열 전송
    • 연결 요청을 받은 서버 프로그램은 클라이언트 프로그램과 연결되자마자 문자열 "Hello World"를 클라이언트 측에 전송.
  3. 화면 출력
    • 클라이언트 프로그램은 전송받은 문자열(Hello World)을 자신의 화면에 출력한다.





저작자 표시
신고

'Win32 API' 를 이용하여 윈도우용 어플리케이션을 개발하기 위해서는 대부분 Microsoft 사의 Visual Studio를 사용할 것이다. 하지만 현재 사용하고 있는 환경이 리눅스 머신이거나 윈도우라 할지라도 Visual Studio 의 개발환경에 구속되지 않고 개발하기 위해서는 어떻게 할 수 있을까?

몇 가지 방법이 존재하겠지만 여기서 소개하는 방법으로 개발환경을 구성하여 진행해 본다.

  • 저작자 표시
    신고

    '그외' 카테고리의 다른 글

    리눅스에서 Win32용 어플리케이션 개발하기  (0) 2013.02.06

함수포인터를 이용한 유용한 기법중 하나인 “메세지 기법”에 대하서 정리했다.

struct MFT_Entry_Attribute_Type
{
    unsigned short	usNum;
    const char *	cDes;
    void (*fp)(void *);
} MFT_Attr_Type[] = {
    { 16, "$STANDARD_INFORMATION", Content_STD_INFO}
    ,{ 32, "$ATTRIBUTE_LIST",0}
    ,{ 48, "$FILE_NAME",Content_FILE_NAME}
    ,{ 64, "$VOLUME_VERSION or $OBJECT_ID",0}
    ,{ 80, "$SECURITY_DESCRIPTOR",0}
    ,{ 96, "$VOLUME_NAME",0}
    ,{112, "$VOLUME_INFORMATION",0}
    ,{128, "$DATA",0}
    ,{144, "$INDEX_ROOT",0}
    ,{160, "$INDEX_ALLOCATION",0}
    ,{176, "$BITMAP",0}
    ,{192, "$SYMBOLICK_LINK or REPARSE_POINT",0}
    ,{208, "$EA_INFORMATION",0}
    ,{224, "$EA",0}
    ,{256, "$LOGGED_UTILITY_STREAM",0}
    ,{257, "Unknown",0}
};
MFT_Entry_Attribute_Type 구조체는
  • 직접적인 비교에 쓰일 변수 한 개와
  • 메세지 출력을 위한 const char * 형의 변수 한 개,
  • 필요에 따라 함수를 호출할 수 있도록 함수 포인터 선언

으로 이루어져 있으며 소스에서 보는 바와 같이 구조체 선언과 동시에 구조체 배열 변수를 선언해 두었다.


이것을 어떻게 사용하는지 아래 소스에서 살펴보면,

void * test(void *p)            /* 213 페이지 */
{
    struct MFT_Entry_Attribute_Type * stpAttType;

    printf("========================= MFT Entry Attribute Analysis =========================\n");
    printf("Attribute Type                   : ");
    stpAttType = MFT_Attr_Type;
    while(1)
    {
        if(257 == (stpAttType->usNum))
        {
            break;
        }
        else if ((*((U32*)((U8*)p+0))) == stpAttType->usNum) /* 이동은 U8만큼으로 하고 보는건 U32로 보겠다 */
        {
            break;
        }
        ++stpAttType;
    }
    printf("%s\n", stpAttType->cDes);
    printf("Lenth of Attribute               : %dBytes\n", *((U32*)((U8*)p+4))); /* 이 길이를 알아내면 #2의 위치를 알 수 있다. */
    printf("Non-Resident Attribute           : %s\n", 1==(*((U8*)p+8)) ? "Yes":"No");
    printf("Lenth of Name                    : %d\n", *((U8*)p+9));
    printf("Offset to Name                   : %d\n", *((U16*)((U8*)p+10)));
    printf("Attribute Flags                  : ");
    if ( 0 != (0x0001 & (*((U16*)((U8*)p+12)))) )
    {
        printf("Compressed ");
    }
    if ( 0 != (0x4000 & (*((U16*)((U8*)p+12)))) )
    {
        printf("Encrypted ");
    }
    if ( 0 != (0x8000 & (*((U16*)((U8*)p+12)))) )
    {
        printf("Sparse ");
    }
    if ( 0 == (0xC001 & (*((U16*)((U8*)p+12)))) )
    {
        printf("Nothing");
    }
    putchar('\n');
    printf("Attribute Identifier             : 0x%04X\n", *((U16*)((U8*)p+14)));

    if(0==(*((U8*)p+8)))	// Resident Attribute 
    {
        printf("=== Resident Attribute========================\n");
        printf("====== Size of Content           : %d\n", *((U32*)((U8*)p+16)));
        printf("====== Offset to Content         : %d\n", *((U16*)((U8*)p+20)));
        printf("====== Index Flag                : %s\n", 1==(*((U8*)p+22)) ? "Yes":"No");
        printf("====== Padding                   : 0x%02X\n", *((U8*)p+23)); /* Reserve ㅇ */
        printf("==============================================\n");
    }
    else					// Non-Resident Attribute 
    {
    }
	
    if(0!=(stpAttType->fp))     /* 호출 함수가 있다면 호출 한다. */
    {
        (stpAttType->fp)(    (U8*)p + (*((U8*)p+20))     ); /* 함수 포인터 */
    }
    return (U8*)p + (*((U32*)((U8*)p+4))) ;
}
  • 3번 줄에서 위에서 선언한 MFT_Entry_Attribute_Type * stpAttType 포인터 변수 선언
  • 7번에서 전역으로 선언된 MFT_Attr_Type을 stpAttType에 대입
  • 8번줄에서 무한 루프를 돌면서 해당하는 값이 있는지 찾고 없으면 다음 값으로
  • 20번줄에서 해당 메세지를 출력
  • 58번줄에서 함수포인터 사용여부를 검사하여 호출 또는 넘어간다.

위와 같은 기법을 이용하면 메뉴 호출또는 메세지등을 손쉽게 할 수 있다.


저작자 표시
신고

'컴퓨터 언어 > C' 카테고리의 다른 글

pThread를 이용한 Thread  (0) 2013.03.05
Static 변수  (0) 2013.02.25
메세지 기법  (0) 2013.01.16
배열의 이름은 첫번째 원소의 주소이다.  (0) 2012.12.20
문자열, 그것은 배열.  (2) 2012.06.11
Makefile을 작성하자.  (2) 2012.06.10


티스토리 툴바