7.4.8 EH 메신저 상태 라이브러리 테스트 [TCP/IP 소켓 프로그래밍 with 윈도우즈]

이번에는 상태 라이브러리가 정상적으로 동작하는지 확인하는 테스트 프로그램을 작성해 봅시다.

먼저 콘솔 응용 프로젝트로 테스트 상태 서버(TracerStsServer)를 추가합니다. 그리고 Program.cpp 소스 파일을 추가하고 필요한 헤더 파일을 포함합니다.

테스트 코드 작성 방법은 테스트 가입 서버와 테스트 로그 서버와 같아서 코드 설명은 생략합니다.

#include "..\\Common\\EHPacket.h"
#include "..\\Common\\KeepAlive.h"
#include "..\\Common\\OtherUserInfo.h"
#include "..\\Common\\ehmsg.h"
#pragma comment(lib,"ws2_32")
#pragma comment(lib,"..\\Debug\\EHPacketLib")
#pragma comment(lib,"..\\Debug\\StsLib")
#include <iostream>
using namespace std;
void StartTestServer();
int main()
{
    WSADATA wsadata;
    WSAStartup(MAKEWORD(2,2),&wsadata);
    StartTestServer();
    WSACleanup();
    return 0;
}

struct in_addr GetDefaultMyAddr();
DWORD WINAPI DoIt(LPVOID pin);
void StartTestServer()
{
    SOCKET sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(sock == -1)
    {
        printf("소켓 생성 실패!\n");
        return;
    }
    SOCKADDR_IN servaddr = {0};
    servaddr.sin_family = AF_INET;//PF_INET;
    servaddr.sin_addr = GetDefaultMyAddr();
    servaddr.sin_port = htons(10200);
    int re = 0;
    re = bind(sock,(SOCKADDR *)&servaddr,sizeof(servaddr));
    if(re == -1)
    {
        printf("bind 실패\n");
        return;
    }
    re = listen(sock,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));
    }
}
struct in_addr GetDefaultMyAddr()
{
    char hostname[256]="";
    gethostname(hostname,255);
    hostent *hentry =  gethostbyname(hostname);
    struct in_addr addr={0};
    while(hentry && hentry->h_name)
    {
        if(hentry->h_addrtype == AF_INET)
        {
            memcpy(&addr,hentry->h_addr_list[0],sizeof(addr));
            return addr;
        }
        hentry++;
    }
    return addr;
}



void KeepAliveProc(SOCKET sock,EHPacket *ep);
void OtherUserInfoProc(SOCKET sock,EHPacket *ep);
DWORD WINAPI DoIt(LPVOID pin)
{
    SOCKET dosock = (SOCKET)pin;
    EHPacket ep(dosock);
    switch(ep.GetMsgId())
    {
    case MID_KEEPALIVE: KeepAliveProc(dosock,&ep); break;
    case MID_USERINFO: OtherUserInfoProc(dosock,&ep); break;
    }
    closesocket(dosock);
    return 0;
}
void KeepAliveProc(SOCKET sock,EHPacket *ep)
{
    KeepAlive ka(ep);
    cout<<"KeepAlive"<<endl;
    cout<<"아이디:"<<ka.GetId()<<"아이피 주소:"<<inet_ntoa(ka.GetIP())<<endl;
    cout<<"상태 포트:"<<ka.GetStsPort()<<" 숏 메시지 포트:";
    cout<<ka.GetSmsgPort()<<" 파일 포트:"<<ka.GetFlePort()<<endl;
}
void OtherUserInfoProc(SOCKET sock,EHPacket *ep)
{
    OtherUserInfo oui(ep);
    cout<<"다른 계정 정보"<<endl;
    cout<<"아이디:"<<oui.GetId()<<endl;
    if(oui.GetSmsgPort() == 0)
    {
        cout<<"로그 아웃"<<endl;
    }
    else
    {
        cout<<"로그 인,"<<" 아이피 주소:"<<inet_ntoa(oui.GetIP())<<endl;
        cout<<" 숏 메시지 포트:"<<oui.GetSmsgPort()<<" 파일 포트:"<<oui.GetFilePort()<<endl;
    }
}

콘솔 응용 프로젝트로 테스트 상태 클라이언트(TracerStsClient)를 추가합니다. 그리고 Program.cpp 소스 파일을 추가하고 필요한 헤더 파일을 포함합니다.

테스트 코드 작성 방법은 테스트 가입(로긴) 클라이언트와 같아서 코드 설명은 생략합니다.

#include "..\\Common\\EHPacket.h"
#include "..\\Common\\KeepAlive.h"
#include "..\\Common\\OtherUserInfo.h"
#include "..\\Common\\ehmsg.h"
#pragma comment(lib,"ws2_32")
#pragma comment(lib,"..\\Debug\\EHPacketLib")
#pragma comment(lib,"..\\Debug\\StsLib")
#include <iostream>
using namespace std;
SOCKET Connect(const char *ip, int port)
{
    SOCKET sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(sock == -1){return -1;}
    SOCKADDR_IN servaddr = {0};
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = inet_addr(ip);
    servaddr.sin_port = htons(port);
    int re = 0;
    re = connect(sock,(SOCKADDR *)&servaddr,sizeof(servaddr));
    if(re == -1){ return -1; }
    return sock;
}
void SendKeepAlive(string id,IN_ADDR ip,int stsport,int smsgport,int fileport)
{
    SOCKET sock;
    KeepAlive ka(id,ip,stsport,smsgport,fileport);
    cout<<"KeepAlive"<<endl;
    cout<<"아이디:"<<ka.GetId()<<"아이피 주소:"<<inet_ntoa(ka.GetIP())<<endl;
    cout<<"상태 포트:"<<ka.GetStsPort()<<" 숏 메시지 포트:"<<ka.GetSmsgPort();
    cout<<" 파일 포트:"<<ka.GetFilePort()<<endl;
    sock = Connect("192.168.34.50",10200);
    ka.Serialize(sock);
    closesocket(sock);
}

void SendOtherUserInfo(string id,IN_ADDR ip,int smsgport,int fileport)
{
    SOCKET sock;
    OtherUserInfo oui(id,ip,smsgport,fileport);
    cout<<"다른 계정 정보"<<endl;
    cout<<"아이디:"<<oui.GetId()<<endl;
    if(oui.GetSmsgPort() == 0)
    {
        cout<<"로그 아웃"<<endl;
    }
    else
    {
        cout<<"로그 인,"<<" 아이피 주소:"<<inet_ntoa(oui.GetIP())<<endl;
        cout<<" 숏 메시지 포트:"<<oui.GetSmsgPort()<<" 파일 포트:"<<oui.GetFilePort()<<endl;
    }
    sock = Connect("192.168.34.50",10200);
    oui.Serialize(sock);
    closesocket(sock);
}
void StartTestClient()
{
    IN_ADDR addr={0};
    addr.s_addr = inet_addr("192.168.34.99");
    SendKeepAlive("hgd",addr,10200,10202,10204);
    memset(&addr,0,sizeof(IN_ADDR));
    SendOtherUserInfo("hgd",addr,0,0);
    addr.s_addr = inet_addr("192.168.34.99");
    SendOtherUserInfo("hgd",addr,10200,10202);
    addr.s_addr = inet_addr("203.168.34.99");
    SendOtherUserInfo("hgd",addr,10200,10202);
    memset(&addr,0,sizeof(IN_ADDR));
    SendKeepAlive("ehpub",addr,0,0,0);
}
int main()
{
    WSADATA wsadata;
    WSAStartup(MAKEWORD(2,2),&wsadata);
    StartTestClient();
    WSACleanup();
    return 0;
}