7.5.2 EH 메신저 – RegSVC 구현 [TCP/IP 소켓 프로그래밍 with 윈도우즈]

RegSVC를 구현합시다. EH 메신저 솔루션에 RegSVC 이름의 콘솔 응용 프로젝트를 만드세요. 그리고 이 책에서는 RegSVC를 구현한 이후에 테스트 프로젝트를 만들고 테스트하는 부분은 다루지 않을게요.

RegSVC 프로젝트에 Program.cpp 파일을 추가하여 소스를 구현합시다.

#include "..\\Common\\EHMessenger.h"
#pragma comment(lib,"ws2_32")
#pragma comment(lib,"..\\Debug\\EHPacketLib")
#pragma comment(lib,"..\\Debug\\RegLib")
#pragma comment(lib,"..\\Debug\\DbmLib")
#pragma comment(lib,"..\\Debug\\EHWrapSocketLib")
#include <iostream>
using namespace std;

진입점 main 함수에서는 윈속을 초기화하고 가입 서버를 가동 후에 윈속을 해제화합니다.

void StartRegServer();
int main()
{
    WSADATA wsadata;
    WSAStartup(MAKEWORD(2,2),&wsadata);
    StartRegServer();
    WSACleanup();
    return 0;
}
DWORD WINAPI DoIt(LPVOID pin);
void StartRegServer()
{
    SOCKET sock = EHWrapSocket::CreateTCPServer(REG_PORT,5);
    SOCKADDR_IN clientaddr;
    int len = sizeof(clientaddr);
    SOCKET dosock;
    DWORD ThreadID;
    while(1)
    {
        dosock = accept(sock,(SOCKADDR *)&clientaddr, &len);
        CloseHandle(CreateThread(0,0,DoIt,(LPVOID)dosock,0,&ThreadID));
    }
}
void RegReqProc(SOCKET sock,EHPacket *ep);
void UnRegReqProc(SOCKET sock,EHPacket *ep);
DWORD WINAPI DoIt(LPVOID pin)
{
    SOCKET sock = (SOCKET)pin;

가입 서버는 가입 요청 메시지나 탈퇴 요청 메시지를 수신하여 이를 처리하는 것을 담당합니다.

    EHPacket ep(sock);
    switch(ep.GetMsgId())
    {
    case MID_REGREQ: RegReqProc(sock,&ep);break;
    case MID_UNREGREQ: UnRegReqProc(sock,&ep); break;
    }
    closesocket(sock);
    return 0;
}

가입 요청 메시지 처리 함수를 작성합시다.

void RegReqProc(SOCKET sock,EHPacket *ep)
{
    cout<<"가입 요청 수신"<<endl;

먼저 수신한 메시지를 가입 요청 메시지로 변환합니다.

    RegReq rr(ep);

그리고 ID 존재 여부 확인 메시지를 생성합니다.

    IDExist ie(rr.GetId());

DBM 서비스에 연결하여 ID 존재 여부 확인 메시지를 전송합니다.

    SOCKET clisock = EHWrapSocket::Connect(DBM_IP,DBM_PORT);
    cout<<"아이디 존재 확인 요청 메시지 전송"<<endl;
    ie.Serialize(clisock);

ID 존재 여부 확인 메시지를 보낸 후에는 응답 메시지를 수신합니다.

    EHPacket rep(clisock);
    closesocket(clisock);

수신한 메시지 메시지가 ID 존재 여부 확인 메시지가 아니면 오류입니다.

    if(rep.GetMsgId() != MID_IDEXISTACK)
    {
        cout<<"오류!!! 아이디 존재 확인 응답 메시지가 아님"<<endl;
        return;
    }

수신한 메시지를 아이디 존재 확인 응답 메시지로 변환합니다.

    cout<<"아이디 존재 확인 응답 메시지 수신"<<endl;
    IDExistAck iea(&rep);
    int result = REG_RES_FAIL;

아이디 존재 확인 응답 메시지의 결과를 확인합니다.

    if(iea.GetResult() == RES_ID_NOTEXIST)
    {

만약 존재하지 않으면 가입 요청 결과는 성공입니다.

        result = REG_RES_OK;
        cout<<"계정 추가 요청"<<endl;

DBM 서비스에 연결하여 계정 추가 메시지를 전송합니다.

        AddUserInfo aui(rr.GetId(),rr.GetPW(),rr.GetName());
        clisock = EHWrapSocket::Connect(DBM_IP,DBM_PORT);
        aui.Serialize(clisock);
        closesocket(clisock);
        cout<<"가입 성공"<<endl;
    }
    else
    {
        cout<<"가입 실패"<<endl;
    }

가입 요청 메시지를 수신한 소켓으로 가입 요청 결과 메시지를 전송합니다.

    RegRes rres(result);
    cout<<"가입 요청 결과 전송"<<endl;
    rres.Serialize(sock);
}

탈퇴 요청 메시지 처리 함수를 작성합시다.

void UnRegReqProc(SOCKET sock,EHPacket *ep)
{
    cout<<"탈퇴 요청 수신"<<endl;
    UnRegReq rr(ep);

탈퇴 요청이 오면 DBM 서비스에게 계정 삭제 요청 메시지를 전송합니다.

    RemoveUser ru(rr.GetId());
    SOCKET clisock = EHWrapSocket::Connect(DBM_IP,DBM_PORT);
    cout<<"계정 삭제 요청 메시지 전송"<<endl;
    ru.Serialize(clisock);
    closesocket(clisock);
}