기타 강좌

#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언어 [비쥬얼 C++ 동영상 강좌] 11회 Application Rc & 클래스 위자드 배우기 1 아방스 2009.01.12 1847
C언어 [비쥬얼 C++ 동영상 강좌] 12회 그림 텍스트 리스트 CListCtrl 클래스 아방스 2009.01.12 1883
C언어 [비쥬얼 C++ 동영상 강좌] 13회 트리 구조 리스트 CTreeCtrl 클래스 아방스 2009.01.12 2592
C언어 같은 그림 맞추기 구현 - 출력,입력 정체불명 2012.01.19 2171
C언어 같은 그림 찾기를 구현 1 정체불명 2012.01.19 2604
C언어 같은 그림맞추기 구현 체크와 엔딩 정체불명 2012.01.19 2251
C언어 같은 그림맞추기 오타정정과 약간 수정한 최종 버전입니다. 3 file 정체불명 2012.01.19 2917
C언어 같은그림찾기 구현 2 초기화 정체불명 2012.01.19 2405
C언어 네트워크 강좌[1]- 기본적인 버클리 소켓을 이용한 프로그래밍 Saber 2010.09.06 4013
C언어 락발라드 구구단~ file 정체불명 2009.05.02 2559
C언어 사각형 테두리 그리기를 연습해봐요 3 file 정체불명 2012.01.21 5701
C언어 소코반 따라만들기 준비 파일읽어배열에담기 정체불명 2012.01.21 2990
C언어 소코반 따라하기 준비 1 파일에서 읽어와서 출력 정체불명 2012.01.21 2857
C언어 소코반 리팩토링 푸쉬푸쉬 file 정체불명 2012.01.25 2573
C언어 소코반 실행파일+소스+스크린샷 file 정체불명 2012.01.25 3521
C언어 소코반(푸쉬푸쉬) 구조 정체불명 2012.01.21 2861
C언어 스릴 쇼크 서스펜스!!!!!!!! 정체불명 2009.05.01 1967
C언어 시작의반 6 file 정체불명 2009.05.01 2167
C언어 알았습니다..그럼 게시물은 다 삭제해버리겠습니다.. 8 제니스 2009.06.16 2278
C언어 정체불명 강의노트 개발툴의 설치 2 정체불명 2009.05.16 2246
Board Pagination Prev 1 2 3 4 5 Next
/ 5