기타 강좌

#1.기본적으로 C언어를 어느정도 안다는 가정하에  내용이 진행이 됩니다.

#2.IDE개발 환경은 아무거나 해도 상관 없지만.  비쥬얼 스튜디오 2005~ 2010까지를 추천드립니다.

네트워크 프로그래밍이라는것은 소켓 프로그래밍이라고 해도

무방합니다. 윈도우 네트워크라는게 상당 부분 리눅스의 BSD소켓 시스템을

차용해서 만들어졌기 때문입니다.

 

 

이번에 보실껏은 버클리 소켓이라고 말을 하기도 하는 기본적인 소켓입니다.

 

비동기 입출력 소켓도 아니고 블럭킹모드로 움직이는 소켓프로그램이지요.

 

물론 MMORPG에서같이 다중 접속을 허용할려면

 

윈도우스 기본적으로 4가지 모델을 사용합니다.

 

1.멀티 쓰레드 모델

2. IO 멀티 플렉싱  모델

3. WSA이벤트 모델

4. IOCP 모델

 

IO멀티 플렉싱 기법은 리눅스의 기반 과 소스코드가 호환됩니다만.

 

기본적으로 동기 알림 모델이라 반응성이 떨어집니다.  접속자의 수는 50명도 넘기기가 힘이 듭니다.

그리고 멀티 쓰레드의 모델같은경우는 전역객체의 임계영역의 지점도 한계가 있고

접속이 하나가 생성될때 마다 하나의 쓰레드를 생성해야 하기 때문에

CPU의 컨텍트 스위칭의 부담감이 있습니다. WSAEVENT의 경우는 비동기 알림이구

비동기 전송 센드로 하면 어느정도 납득할만합니다.

물론.. 윈도우에서 최고의  네트워크 모델은 IOCP이겠지만요..

 

하지만 이것은 나름대로 복잡한 로직이 필요하니 간단하게

기본적으로 버클리 소켓을 이용한 간단한 동기 입출력 모델을 보도록 하겠습니다.


서버 프로그램 내에서는 서버 소켓을 하나 만들어 둡니다. 

뭐 만든다고 해도 소켓 자체는 window 운영체제가 만들어 줍니다.

그리고 운영체제가 만들면서 소켓의 핸들을 리턴받습니다.

마치 윈도우 운영차제에서 윈도우 창을 만들때 와 비슷하죠?

마찬가지로 소켓을 만들면 윈도우에서 핸들을 주는데

우리는 이 핸들도 여러가지를 합니다.

일단 여기서는 1:1 접속의 구조라서 서버에서는 서버소켓 1개와 클라이언트 소켓 1개

이렇게 밖에 없습니다. 동시접속구조를 꾸미고 싶다면 select구조로 작성하거나 IOCP로

작성해야 합니다만. 상당히 난이도가 높은 코드를 요합니다.


그럼 서버의 구조는 어떻게 될까요 ?

일단 윈도우 소켓 프로그래밍을 할려면 라이브러리를 초기화 해줘야 하는데

다음함수가 초기화를 해줍니다. 

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

모든 윈도우 소켓 프로그래밍은 무조건 WSAStartup함수가 호출 되어야 합니다.

윈도우 소켓 2.2버젼을 사용한다는 뜻이고 WSADATA는  하나 선언해서 

주소값을 넘기면 됩니다. 


그리고 나서 socket(PF_INET,  SOCK_STREAM, IPPROTO_TCP) 함수로 서버 소켓을

일단 만들어둡니다. 대충 보면 TCP 프로토콜의 소켓을 만든 다는 뜻인데요. 

서버 소켓이라는 것은 일종의 문지기를 담당합니다. 클라이언트에서 접속을 요청할

경우 접대를 해줄 소켓이 필요한데 이역활을 서버 소켓이 담당합니다..


bind(hServerSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) 함수로

서버컴퓨터의 ip값이랑 포트값을 할당합니다. 전화기를 애를들어보져

전화를 걸려면(클라이언트)  상대방(서버) 번호가 있어야겠지요?

bind는 전화국에 가서 번호를 따오는 것과 똑같은 일을 합니다..



listen함수로 연결 요청 대기 상태로 들어갑니다. 이때부터 이때부터

클라에서 연결을 요청할수 있습니다. 하지만 연결요청에 대한 응답을 해야 하는데!

다음의 함수를 연결요청을 수락 할수 있습니다.

 hClientSocket = accept(hServerSocket, (SOCKADDR*)&clientAddr, &iClientAddrSize)

연결이 요청되고 나서 이제부터 데이터의 송수신이 가능한데

send함수랑 recv함수로 송수신이 가능합니다.


그리고 송수신이 끝나고 나면  소켓을 닫아주어야 합니다. 다음의 함수로 닫아 줄수가

있습니다.

 closesocket(hServerSocket);


다음으로 윈속 라이브러리를 올렸으니 반대로 깨긋하게 닫아줘야겠지요?

다음의 함수로 닫아줍니다.

 WSACleanup();


클라이언트의 코드를 볼까요 바인드 함수 연결 함수 이런거 전혀 필요없습니다.

그냥 바로 소켓생성하고  커넥트 함수 호출해주시면 준비가 끝납니다.

connect(hSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr))




프로젝트 생성하실때는 win32 콘솔 어플리케이션으로 생성해서 설정하고

초기설정에서는 빈프로젝트에 체크를 해주세요


그럼 소스를 볼까요 프로젝트 속성 -> 구성 속성 -> 문자열 집합

을 멀티 바이트 문자 집합으로 바꿔주시고 다음에 소스코드를 확인 하여 보세요


*서버 소스 코드
#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
#include <windows.h>
#pragma comment(lib, "ws2_32.lib")

CONST INT MAX_LISTENING_QUEUE = 5;
static CHAR g_szPort[] ="3587";

INT main(VOID)
{
    WSADATA wsaData;
    SOCKET hServerSocket;
    SOCKET hClientSocket;
    SOCKADDR_IN serverAddr;
    SOCKADDR_IN clientAddr;

    INT iClientAddrSize ;

    CHAR message[] = "검은 고양이 네로 네로 네로 이랬다 저래 나 장난꾸러기~!!";

    if ( WSAStartup( MAKEWORD(2, 2), &wsaData) != 0 )
     {
        puts("WSAStartup() 함수 에러");
        exit(1);
     }

    hServerSocket = socket(PF_INET,  SOCK_STREAM, IPPROTO_TCP);
    if ( hServerSocket == INVALID_SOCKET )
     {
        puts("서버 소켓 핸들 에러") ;
        exit(1);
     }

    ZeroMemory(&serverAddr, sizeof(serverAddr)) ;
    serverAddr.sin_family = AF_INET ;
    serverAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    serverAddr.sin_port = htons(atoi(g_szPort));


    if ( bind(hServerSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR )
     {
        puts("바인드 함수가 정상적으로 작동되지 못하였습니다.");
        exit(1);
     }

    if ( listen(hServerSocket, MAX_LISTENING_QUEUE) == SOCKET_ERROR )
     {
        puts("리슨 함수가 제대로 작동되지 못하였습니다.");
        exit(1);
     }

    iClientAddrSize = sizeof( clientAddr );
    hClientSocket = accept(hServerSocket, (SOCKADDR*)&clientAddr, &iClientAddrSize);

    if (hClientSocket == INVALID_SOCKET)
     {
        puts("클라이언트 소켓이 잘못되었습니다.!!");
        exit(1);
     }

    send(hClientSocket, message, sizeof(message), NULL);

    closesocket(hServerSocket);
    closesocket(hClientSocket);
    WSACleanup();
    return 0; 
}






*클라이언트 소스 코드
#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
#include <windows.h>
#pragma comment(lib, "ws2_32.lib")

static CHAR g_szIP[] = "127.0.0.1";
static CHAR g_szPort[] ="3587";

INT main(VOID)
{
    WSADATA wsaData;
    SOCKET hSocket;
    SOCKADDR_IN serverAddr;

    CHAR message[100];
    INT iMessageLen;

    if ( WSAStartup( MAKEWORD(2, 2), &wsaData) != 0 )
     {
        puts("WSAStartup() 함수 에러");
        exit(1);
     }

    hSocket = socket(PF_INET,  SOCK_STREAM, IPPROTO_TCP);
    if ( hSocket == INVALID_SOCKET )
     {
        puts("소켓 핸들 에러") ;
        exit(1);
     }

    ZeroMemory(&serverAddr, sizeof(serverAddr)) ;
    serverAddr.sin_family = AF_INET ;
    serverAddr.sin_addr.S_un.S_addr = inet_addr(g_szIP);
    serverAddr.sin_port = htons(atoi(g_szPort));

    if ( connect(hSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR )
     {
        puts("접속이 끊겼음....");
        exit(1);
     }
 
    iMessageLen = recv(hSocket, message, sizeof(message), 0);
 
    if (iMessageLen == -1)
    {
        puts("EOF입니다.");
        exit(1);
    }

    MessageBox(NULL, message, "ServerMessage", MB_OK);   

    closesocket(hSocket);
    WSACleanup();
    return 0; 
}

 


List of Articles
분류 제목 글쓴이 날짜 조회 수
Vegas Pro 베가스 강좌 목록 아방스 2017.09.28 886
파이널컷X 파컷 강좌 목록 아방스 2017.06.18 757
기타 게임제작에 실패하는이유는? 3 rlawnsahXP 2010.10.03 2313
기타 프로그래밍 스킴 Scheme 2 프로그래밍한 걸 exe파일 만들어 배포하기! 2 file 정체불명 2010.10.02 3156
기타 프로그래밍 스킴 Scheme 1 다운로드부터 문법 대부분을 314초만에 알려줄게요 9 file 정체불명 2010.10.02 4828
기타 시나리오 작법 서론 종합 4 wigen 2010.09.26 2178
기타 게임 기획에 관한 기법들 3 아방스 2010.09.15 3249
기타 온라인 게임 서버의 구조도 4 file Saber 2010.09.06 2509
C언어 네트워크 강좌[1]- 기본적인 버클리 소켓을 이용한 프로그래밍 Saber 2010.09.06 4013
시네마4D Cinema4D 맵핑, 매터리얼 기초 메뉴얼 아방스 2010.08.18 3515
C언어 C# - 시스템 정보 받기 2 file 코르뉴 2010.07.11 2831
에프터 이펙트 에픽 플러그인 키젠에 대한 간단한 팁 ^^ 아방스 2010.06.09 3980
에프터 이펙트 총 쏘는 듯한 효과를 만들어 볼까요? 7 아방스 2010.06.01 5784
기타 컴퓨터에 설치된 코덱 확인방법 아방스 2010.05.31 2232
기타 JHL's STUDY_캐릭터의 중심 "콘티" file J H L 2010.04.02 2197
플러그인 에펙.프리미어 플러그인 RedGiant.KnollLightFactoryPro v2.5.2 1 file 아방스 2010.03.23 5899
플러그인 에펙 플러그인 Zaxwerks 5가지 최신버젼 아방스 2010.03.23 5899
플러그인 [AE Plug-in]RedGiant.Holomatrix.v1.0 file 아방스 2010.03.23 3654
플러그인 [AE Plug-in] RedGiant.Magic Bullet Suite 2009! 3 file 아방스 2010.03.20 4437
C언어 코르뉴의 자료구조 기초 - 자기 참조 구조체(1/3) 코르뉴 2009.12.11 2924
기타 [파이썬] 함수 (플밍을 편하게))10( 4 - 하늘 - 2009.10.26 2440
기타 [파이썬] for문 (여러 번 반복하기))9( 6 - 하늘 - 2009.09.11 3877
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Next
/ 19