티스토리 뷰

개요


socket으로 네트워크 엔진 만들기 (1) 에서 만든 패킷을 활용하기 위해서 socket이 제공하는 함수들을 사용할 수도 있지만

Packet을 보내거나 읽고, 읽은 내용을 파싱하여 필요한 함수를 호출할 수 있도록 하는 등 여러 기능들을 추상화시킨 class가 있으면 사용하기 편할 것이다.

NetworkManager class를 만들어 보자.

NetworkManager class의 이름은 network를 가장 잘 manage하는 생물인 Spider로 하자.


network를 가장 잘 manage하는 사람







Spider - socket을 생성하고 연결하기


Spider는 싱글톤으로 구현되어 프로그램에 유일하게 존재하며, 하나의 socket을 가지고 통신한다. 사용자는 ip, port를 설정하는 것으로 서버 또는 다른 클라이언트와 연결할 수 있다.

먼저 서버로 연결할 소켓을 만드는 예시를 보며 어떻게 사용하는지 파악한 후, 내부 코드를 설명하겠다.


예제

156.244.2.15:9965 로 접속하는 소켓 생성


1
2
3
4
5
void MakeSocket{
    Spider::Instance()->SetAddr(9965"156.244.2.15");
    Spider::Instance()->OpenSocketAsGuest();
}
 

cs


Spider의 싱글톤으로 접근해서 주소를 설정하고, 설정된 주소로 소켓을 생성한다. 이제 Spider::Instance()->Send() 를 호출하면 열린 소켓을 통해 패킷을 전송할 수 있다.


내부적으로 동작하는 코드를 보자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Spider.h
 
// ...
 
class Spider{
private:
    SOCKET _socket;
    struct sockaddr_in _addr;
 
    Spider();
 
    static Spider* _instance;
 
public:
    /** singletone **/
    static Spider* Instance();
    static void DeleteInstance();
 
    void SetAddr(long port, const char* ip); // connect하거나 bind할 주소를 설정한다.
 
    int OpenSocketAsHost(); // host 기능을 하는 소켓을 만든다.
    int OpenSocketAsGuest(); // guest 기능을 하는 소켓을 만든다.
 
    // ...
 
};
 

cs


OpenSocketAsHost()는 host기능을 할 소켓을 만드는 함수로 p2p 환경에서 host가 될 때 사용할 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int Spider::OpenSocketAsHost(){
    int ret = 0;
 
    if(_socket)
        CloseSocket();
 
    _socket = socket(AF_INET, SOCK_STREAM, 0);
 
    ret = bind(_socket, (struct sockaddr*)&_addr, sizeof(_addr));
 
    if(ret<0)
        return ret;
 
    listen(_socket, 5);
 
    /** WSAAsyncSelect
    * 두번째 인자는 윈도우 핸들인데 윈도우 생성을 담당하는 App class로부터 얻어온다.
    * WM_SOCKET은 define 값으로  #define WM_SOCKET WM_USER+1  이다.
    * 호스트로 사용할 것이므로 accept, read, close 이벤트를 기다린다.
    **/
    ret = WSAAsyncSelect(_socket, App::Instance()->GetHWND(), WM_SOCKET, FD_ACCEPT | FD_READ | FD_CLOSE);
 
    return ret;
}
 
cs


OpenSocketAsGuest()는 guest기능을 할 소켓을 만드는 함수로 서버에 연결하거나 host에게 연결할 때 사용할 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int Spider::OpenSocketAsGuest(){
    int ret = 0;
 
    if(_socket)
        CloseSocket();
 
    _socket = socket(AF_INET, SOCK_STREAM, 0);
 
    ret = connect(_socket, (struct sockaddr*)&_addr, sizeof(_addr));
 
    if(ret<0)
        return ret;
 
    /** WSAAsyncSelect
    * 게스트로 사용할 것이므로 connect, read, close 이벤트를 기다린다.
    **/
    ret = WSAAsyncSelect(_socket, App::Instance()->GetHWND(), WM_SOCKET, FD_CONNECT | FD_READ | FD_CLOSE);
 
    return ret;
}
 
cs


댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함