|
LOG SERVER & FRONT SERVER
SunMoon BIT 21th 유미영 |
- Contents -
n Program 목적
n LOG &FRONT_SERVER의 역할
n Architecture
n 구성요소
n 기술
n 결과
|
Program 목적 |
본 프로그램의 목적은 우리가 찾고 싶은 자료에 더 근접하게 다가갈 수 있는 시멘틱 검색엔진의 기술을 익히고자 한다. |
FRONT_END SERVER의 역할 |
FRONT_END SERVER는 데이터의 내용을 알 필요가 없이 메시지만 판단하여 by-pass한다. P2P 사용자의 메시지가 Client Server로부터 전달 되어 FRONT_END SERVER는 받은 메시지가 어떠한 메시지인지를 파악하고 메시지에 맞는 해당 서버로 메시지와 데이터를 보내준다. |
Front Server - Architecture | |
|
클라이언트에서 가입 요청 시 회원 가입 서버(RegServer)로 데이터를 보내준다.
요청에 대한 응답이 오면 클라이언트 서버로 데이터를 보내준다.
Front Server - Architecture | |
|
클라이언트에서 로그인 요청 시 로그인 서버(LogServer)로 데이터를 보내준다.
요청에 대한 응답이 오면 클라이언트 서버로 데이터를 보내준다.
Front Server - Architecture | |||
|
클라이언트에서 로그아웃 요청 시 Log Server로 데이터를 보내준다.
Front Server - Architecture | ||
|
클라이언트에서 자신이 살아있다는 KeepAlive 메시지를 지속적으로 받는다. 받는 메시지를 상태서버로 보내준다. 로그인 요청 성공시 클라이언트정보가 오게 되면 상태서버(Status Server)에게 데이터를 보내준다.
Log Server의 역할 |
Front Server에서 받은 데이터를 읽거나 쓰기 위해 Database로 전송해 주는 역할을 한다. |
Log Server - Architecture |
|
구성요소 |
| |
분류 |
개수 |
비고 |
프로젝트 |
1 |
Front |
DLL |
10 |
REG_REQ, LOG_REQ, LOGIN_RES, LOGOUT_REQ,SEND_STATUS, LOGMEM_REQ,LOGMEM_ANS ,CHANGE_STATUS,KEEPALIVE_STS |
서버 수 |
1 |
FrontServer+LogServer |
exe |
9 |
가상Client(로그인,로그아웃), FrontServer(로그인,로그아웃) |
Window 수 |
DLL개수만큼 |
Consol창으로 DLL만들기 전 상태 확인 Test용 Server&클라이언트 Win32API MFC로 가상클라이언트만들어서 Server와 Test |
기술 |
1. 소켓 통신
<소켓통신을 위해 초기화 하는 Class> void CLogServerDlg::ServProc() { UpdateData(true); THREADPAPAMS *thread = new THREADPAPAMS; Document *pDoc = Document::GetMyDocument(); thread->pWnd = this; CWinThread *Serv = AfxBeginThread(pDoc->ServThreadProc,thread); UpdateData(false); } UINT Document::ServThreadProc(LPVOID pin) { WSADATA wsd; WSAStartup(MAKEWORD(2,2),&wsd); THREADPAPAMS *thread = (THREADPAPAMS *)pin;
SOCKET sock = socket(AF_INET,SOCK_STREAM,0); SOCKADDR_IN serv_addr = {0,}; serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = gethostip(); serv_addr.sin_port = htons(10200); int re = bind(sock,(SOCKADDR *)&serv_addr,sizeof(serv_addr)); re = listen(sock,5); SOCKET dosock; SOCKADDR_IN client_addr = {0,}; int c_len = sizeof(SOCKADDR_IN);
while(1) { int re = dosock = accept(sock,(SOCKADDR *)&client_addr,&c_len); thread->sock = dosock; CWinThread *pThread = AfxBeginThread(ServDoIt,thread); } WSACleanup(); return 0; } |
2. 패킷화
*전송할 데이터의 패킷화 예)Login요청 시 id,pw,frdInfo,file,etc의 데이터를 패킷화 ******************************************************************************************************* LogInReq::LogInReq(wchar_t *id,wchar_t *pw,SOCKADDR_IN frdinfo, SOCKADDR_IN file, SOCKADDR_IN etc):EhPacket(LOG_REQ) { //*************id Packetizing idlen = (lstrlen(id)+1)*2; Packetizing(&idlen,sizeof(int)); Packetizing(id,idlen); //*************pw Packetizing pwlen = (lstrlen(pw)+1)*2; Packetizing(&pwlen,sizeof(int)); Packetizing(pw,pwlen); //*************frdinfo,file,etc Packetizing Packetizing(&frdinfo,sizeof(SOCKADDR_IN)); Packetizing(&file,sizeof(SOCKADDR_IN)); Packetizing(&etc,sizeof(SOCKADDR_IN)); } ******************************************************************************************************* LogInReq *LogInReq::MakeInstance(SOCKET sock) { MsgHead mh; int re = recv(sock,(char *)&mh,sizeof(mh),0); //보낸패킷을받는다. if(mh.msgid != LOG_REQ) { return 0; } LogInReq *logreq = new LogInReq(sock,mh.bdlen); return logreq; } ******************************************************************************************************* LogInReq::LogInReq(SOCKET sock,int bdlen):EhPacket(LOG_REQ) { char tempbase[MAX_PACKET_SIZE]; //******소켓에 임시보관장소에 body길이만큼 받아 recv(sock,tempbase,bdlen,0); Packetizing Packetizing(tempbase,bdlen); } *Packetizing한 데이터를 UnPacket하여 확인을 할 때 사용하는 함수들 ******************************************************************************************************* void LogInReq::GetID(wchar_t *dst, int bsize) { int idlen = 0; Reset(); UnPacketizing(&idlen,sizeof(int)); //id len을먼저얻고 UnPacketizing(dst,idlen); //idlen만큼언패킷해달라. Reset(); } void LogInReq::GetPW(wchar_t *dst, int bsize) { Reset(); UnPacketizing(&idlen,sizeof(int)); UnPacketizing(id,idlen);
UnPacketizing(&pwlen,sizeof(int)); UnPacketizing(dst,pwlen); Reset(); } void LogInReq::GetFileSessionInfo(SOCKADDR_IN *file) { Reset(); UnPacketizing(&idlen,sizeof(int)); UnPacketizing(id,idlen); UnPacketizing(&pwlen,sizeof(int)); UnPacketizing(pw,pwlen);
UnPacketizing(&temp,sizeof(SOCKADDR_IN)); //temp에는 frdinfo가 들어있음. UnPacketizing(file,sizeof(SOCKADDR_IN)); Reset(); } |
3. DLL
*DLL화 할 클래스 헤더 부분 ******************************************************************************************************* #ifdef SDJFIEJKSDFH_29EICEK_SDFEI34_safeIEF #define DLLLOGIN __declspec(dllexport) #else #define DLLLOGIN __declspec(dllimport) #endif class DLLLOGIN LogInReq:public EhPacket { . . . }; *DLL화 할 클래스 소스 부분 ******************************************************************************************************* #define SDJFIEJKSDFH_29EICEK_SDFEI34_safeIEF 선언 |
4. PacketFactory
EhPacket *PacketFactory::MakePacket(SOCKET sock) { MsgHead mh; int re = recv(sock,(char *)&mh,sizeof(mh),0); //보낸패킷을받는다. switch(mh.msgid) { case LOG_REQ: return new LogInReq(sock,mh.bdlen);break; } return 0; } LogInReq *PacketFactory::ConvertLogInReq(EhPacket *ehpacket) { if(ehpacket->GetMsgId() == LOG_REQ) { return dynamic_cast<LogInReq *>(ehpacket);//EhPacket * -> LogReq * (형변환),NULL이라면에러 } return 0; } |
기타 |
모든 부분을 다 구현시키지는 못하였다.
결과 |
Front Server는 로그인, 로그 아웃 등 Client가 Log, Status, Reg 등 Server에게 요청할 때 바로 해당 Server로 가지 않고 Front Server에서 해당하는 Server에게 by-pass로 그 데이터 요청 신호를 보내 주는 역할을 한다. 이 프로그램은 클라이언트가 로그인 , 로그 아웃 요청 시 FrontServer, LogServer가 한데 뭉쳐 있어서 육안으로 Front Server와 LogServer를 나눠 보기는 힘들다. 기간 내에 모든 부분을 구현하지 못한 이유는 팀원 간에 job분배도 제대로 하지 못하였고 팀원 내에 조금 더 확실한 규약을 지정해야 했던 것 같다. 이 문제를 해결하기 위해서 팀원끼리 각자 담당 Part 구현을 위한 노력과 시간 분배를 제대로 해야 할 것이다.
실행결과 |
|
가상 Client를 만들어 로그인 창을 띄워 아이디, 비밀번호를 입력하여 로그인을 하게 된다. |
|
클라이언트에서 로그인 시, 로그인 상태 버튼이 활성화되면서 아래의 항목에 로그인 된 회원의 정보가 나타난다. |
|
로그인 된 상태에서, 로그 아웃을 하게 된다. |
클라이언트에서 로그아웃 시,로그인 버튼이 비활성화 되면서 로그아웃 버튼이 활성화 된다. 그리고 아래의 항목에 로그아웃 상태가 뜬다. |
|