기타 강좌

#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
C언어 네트워크 강좌[1]- 기본적인 버클리 소켓을 이용한 프로그래밍 Saber 2010.09.06 4013
기타 내가 생각해낸 방법 [SE-BAND] 7 비타스 2008.07.07 2435
기타 글쓸떄 본문에 이미지 삽입 하는법. 5 file 작은악마 2008.05.18 2665
기타 그림판으로 아이콘 만들기 4 검은별 2009.07.13 3395
그래픽1개를 다운받아서 2개로 사용방법 어두운동굴 2008.07.29 2442
기타 그래픽 드라이버 삭제 및 재설치 방법 1 아방스 2009.05.28 3099
기타 게임줄거리를 만들어볼까?!! 6 칼리아 2009.08.01 2522
기타 게임제작에 실패하는이유는? 3 rlawnsahXP 2010.10.03 2313
기타 게임제작 관련 학과들 7 아방스 2009.03.12 3061
기타 게임을 처음 제작하시는 초심자 분들께 7 TheEK 2012.07.03 2560
게임기획 게임기획에 대한 강의2 1 현준갓 2015.11.01 651
게임기획 게임기획에 대한 강의1 2 현준갓 2014.12.15 1344
게임기획 게임,개발기획의 기초 9 file 공룡칸드 2011.07.31 2904
기타 게임 엔진, 그것이 궁금하다. 7 아방스 2008.03.22 2718
기타 게임 엔진 中 [렌더링 엔진] 비교 3 아방스 2011.10.24 3425
게임 업로드 방법 아방스 2009.01.06 1857
기타 게임 기획에 관한 기법들 3 아방스 2010.09.15 3249
XpressEngine 게시물의 추천/비추천 기능 추가하기 1 아방스 2009.07.09 4895
기타 거북명령 프로그램으로 별모양으로 동그라미로 하기 5 프로즌 2008.04.19 7478
C언어 같은그림찾기 구현 2 초기화 정체불명 2012.01.19 2405
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Next
/ 19