Blocking Model

퍼스널 컴퓨터에서 클라이언트가 접속해서 지속해서 데이터르 주고 받을때


Non-Blocking Model

AsyncSelec(윈도우), EventSelect  (콘솔,백그라운드)

퍼스널 컴퓨터에서 동작 시키고자 할 때 해당되는 소켓을 가지고 실질적으로 패킷을 주고 받는게

지속적으로 주고 받는게 아니라 단편적으로 데이터를 주고 받을 때

Overlapped I/O

이벤트 셀렉트처럼 사용  할 수 있다. 폴링에 관한 비용이 들지 않는다.


다수의 CPU를 가지고 있을 때 CPU를 최대한 사용 할 수 있다.
Contex Switching 발생이 하지 않는다.



1. Listen Thread + n개의 Thread(1 Client를 위해 1개의 Thread)

    - Personal Computer상에서 개인 용도의(중요도가 적은) Server를  운용할 때

    - Client와 Server간의 흐름이 지속적일 때

       *소켓 통신외에 다른 작업은 별도의 쓰레드에게 관리를 하자.

장점

     Client 1개와의 통신에 대한 논리만 생각할 수 있게 해 준다.

단점 

    쓰레드의 생성과 소멸에 대한 비용이 많이 든다.

    context/switching에 대한 비용이 많이 든다. 

 

 2. AsyncSelect

   - 소켓 통신외에 다른 작업이 병행되어야 할 경우

   - Client와 Server간의 흐름이 단발적일 때 

   - 해당 쓰레드에 메시지를 받을 수 있는 window가 존재할 때 

      *눈에 보이지 않는 빈껍데기 msessage window여도 상관 없음 

장점

     소켓 통신을 위한 별도의 쓰레드 자원을 사용하는 비용이 필요없다.

     받은 패킷 종류에 따라 나누어서 해당 패킷에 대해서 작성을 해 나갈 수 있다.

단점  

    패킷 처리에 드는 비용이 많이 드는 경우에 비효율적이 될 수 있다.    

   받은 패킷 종류에 따라 나누어서 해당 패킷에 대해서 작성을 하지 않으면 비효율적이 될 수 있다.

    다수의 CPU를 장착한 시스템에서 모든 CPU를 사용하지 않게 된다. 

 

3. EventSelect

   - 소켓 통신외에 다른 작업이 병행되어야 할 경우

   - Client와 Server간의 흐름이 단발적일 때 

   - 해당 쓰레드에 메시지를 받을 수 있는 window가 존재하지 않을 때 

장점

     소켓 통신을 위한 별도의 쓰레드 자원을 사용하는 비용이 필요없다.

     받은 패킷 종류에 따라 나누어서 해당 패킷에 대해서 작성을 해 나갈 수 있다.

단점  

    패킷 처리에 드는 비용이 많이 드는 경우에 비효율적이 될 수 있다.    

    어느 정도의 Polling이 따르게 된다. 

   받은 패킷 종류에 따라 나누어서 해당 패킷에 대해서 작성을 하지 않으면 비효율적이 될 수 있다.

    다수의 CPU를 장착한 시스템에서 모든 CPU를 사용하지 않게 된다. 

 

4. Overlapped I/O

    - Personal Computer상에서 Server를  운용할 때

    * 소켓 통신외에 다른 작업이 병행되어야 될 경우에는 세심한 주의가 필요하거나 다른 방법을 찾아보자.

 

장점

     소켓 통신을 위한 별도의 쓰레드 자원을 사용하는 비용이 적게 든다.

     비동기 소켓 통신이기 때문에 많은 client에 많은 패킷 흐름을 효율적으로 사용할 수 있다. 

단점  

    다수의 CPU를 장착한 시스템에서 모든 CPU를 사용하지 않게 된다. 

  

5. IOCP

    - Server System에 O/S가 Windows O/S일 경우

    - 다른 응용이 동작할 개연성이 매우 적을 경우 

장점

    다수의 CPU를 장착한 시스템에서 모든 CPU를 Full로 사용할 수 있다.

단점  

    CPU를 사용하는 다른 응용이 많을 경우 큰 이득이 없다.




출처 http://cafe.daum.net/sbehclub

'API & MFC > 네트워크프로그래밍' 카테고리의 다른 글

EventSelect란?  (0) 2010.02.05
ASyncSelect 예제  (1) 2010.02.04
소켓함수 예제(로그인서버)  (0) 2010.01.25
소켓통신(함수정리)  (1) 2010.01.18
OSI 모델 And Ip계층  (0) 2010.01.18
Posted by 아몰라

#pragma comment(lib , "dll.lib")
#include "Packet.h"
#include "Channel.h"
#include <stdio.h>


///////////////////////////////////////////////////////////////
typedef struct MemberInFo
{
 char *Id;
 char *Pass;
 char *Name;
 int Idlen;
 int Passlen;
 int Namelen;
 int C_Port;
 int SmsPort;
 int FilePort;
 LONG C_Ip;
}MemberInFo;

MemberInFo * member = new MemberInFo();

////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////

void Load(); //Log서버 초기화 후 대기
DWORD WINAPI Send(LPVOID temp); //Login 과 Logout에게 DB서버 정보 전송

void LoginReq(Packet * pack, MsgHead msg, SOCKET sock_Log, SOCKET sock_Db);
void LoginPack(SOCKET sock_Db); //로그인 팩
void LoginUnPack(Packet * pack); //로그인 언팩

void LogoutReq(Packet * pack, MsgHead msg, SOCKET sock_Db); 

int SearchAck(SOCKET sock_Log); //DB로부터 값을 받아서 리턴
void SetState();    //아이디가 있을경우 State 서버로 회원포트정보 등 전송
void SendState(Packet *Pack); //State 서버 초기화

///////////////////////////////////////////////////////////////////

 

int main()

 WSADATA wsaData;
 WSAStartup(MAKEWORD(2,2), &wsaData);
 
 
 
 AllocConsole();
 freopen("conout$","wt",stdout);

 while(1)
 {
  Load();
 } 


 WSACleanup();

 
 delete member;

 return 0;
}


void Load()
{
 DWORD ThreadID;
 SOCKET sock_Log = OpenSocket(LOGSV_IP_ADDR, S_LOG);
 SOCKADDR_IN clientaddr={0,};
 int len = sizeof(clientaddr);
 
 
 SOCKET dosock;

 while(1)
 {
  printf("대기중\n");
  dosock = accept(sock_Log,(SOCKADDR *)&clientaddr,&len); 
  CloseHandle(CreateThread(NULL,0,Send,(LPVOID)dosock,0,&ThreadID));

 }
 closesocket(dosock);
 closesocket(sock_Log);

}

 

DWORD WINAPI Send(LPVOID temp)
{
 SOCKET sock_Log = (SOCKET)temp;
 
 MsgHead msg(sock_Log);  // Msgid 와 Bodylen을 가져온다.  4 + 4
 Packet * pack = new Packet(sock_Log, msg.Getblen()); //  Bodylen 만큼 데이터를 가져온다
 printf("%d", msg.GetMsgid());
 int msgid = msg.GetMsgid();
 
 SOCKET sock_Db = OpenSocket(DBM_IP_ADDR, S_DBM,0);  //Db 와의 연결
 

 switch(msgid)
 {
 case LOGIN: LoginReq(pack, msg, sock_Log, sock_Db); break;
 case LOGOUT: LogoutReq(pack, msg, sock_Db); break;
 default: break;
 }

 
 closesocket(sock_Log); 


 return 0 ;
}

 

void LoginReq(Packet * pack, MsgHead msg, SOCKET sock_Log, SOCKET sock_Db)
{
 int Ack;

 LoginUnPack(pack);
 LoginPack(sock_Db);

 
 if((Ack = SearchAck(sock_Db)))
 {
  send(sock_Log, (char*)&Ack, sizeof(int), 0);
  SetState();
  closesocket(sock_Log);
 }
 else
 {
  send(sock_Log, (char*)&Ack, sizeof(int), 0);
  closesocket(sock_Log);
 }
 
 delete pack;
 closesocket(sock_Db);
}


void LoginUnPack(Packet * pack)
{
 pack->UnPack(&member->Idlen, sizeof(member->Idlen));
 member->Id = new char[member->Idlen];
 pack->UnPack(member->Id, member->Idlen);
 pack->UnPack(&member->Passlen, sizeof(member->Passlen));
 member->Pass = new char[member->Passlen];
 pack->UnPack(member->Pass, member->Passlen);
 pack->UnPack(&member->C_Ip, sizeof(member->C_Ip));
 pack->UnPack(&member->C_Port, sizeof(member->C_Port));
 pack->UnPack(&member->SmsPort, sizeof(member->SmsPort));
 pack->UnPack(&member->FilePort, sizeof(member->FilePort));

 printf("ID:%s, Pass:%s, IP:%d, C_Port:%d, SPort:%d, FPort:%d", member->Id, member->Pass, member->C_Ip, member->C_Port, member->SmsPort, member->FilePort);
}


void LoginPack(SOCKET sock_Db)
{
 MsgHead msg2(LOGIN);

 int bodysize = sizeof(member->Idlen) + member->Idlen + sizeof(member->Passlen) + member->Passlen;

 msg2.SetBlen(bodysize);
 
 Packet * pack2 = new Packet();
 
 pack2->Pack(&msg2, sizeof(MsgHead));
 pack2->Pack(&member->Idlen, sizeof(member->Idlen));
 pack2->Pack(member->Id, member->Idlen);
 pack2->Pack(&member->Passlen, sizeof(member->Passlen));
 pack2->Pack(member->Pass, member->Passlen);
 
 pack2->Send(sock_Db);

 delete pack2;
}

 

void LogoutReq(Packet * pack, MsgHead msg, SOCKET sock_Db)
{

 pack->RePack(&msg, sizeof(MsgHead)); 
 
 pack->Send(sock_Db);
 
 SendState(pack);
 
 
 delete pack;
 closesocket(sock_Db);

 
}

 

int SearchAck(SOCKET sock_Log)  //db로부터 받은 True False 반환!
{
 int re;

 recv(sock_Log, (char*)&re, sizeof(int),0);
  
 printf("\n%d", re);
 
 
 return re;
}

 

void SetState()
{
 MsgHead msg(LOGIN);

 int bodysize = sizeof(member->Idlen) + member->Idlen + sizeof(member->C_Ip) + sizeof(member->C_Port) + sizeof(member->SmsPort) + sizeof(member->FilePort);

 msg.SetBlen(bodysize);
  
 Packet * pack = new Packet();
 
 pack->Pack(&msg, sizeof(MsgHead));
 pack->Pack(&member->Idlen, sizeof(member->Idlen));
 pack->Pack(member->Id, member->Idlen);
 pack->Pack(&member->C_Ip , sizeof(member->C_Ip));
 pack->Pack(&member->C_Port, sizeof(member->C_Port));
 pack->Pack(&member->SmsPort, sizeof(member->SmsPort));
 pack->Pack(&member->FilePort, sizeof(member->FilePort));

 printf("SetState : %d, %d\n",member->C_Ip,member->C_Port);

 
 SendState(pack);

 delete pack;
}

void SendState(Packet *Pack)
{
 SOCKET sock_State = OpenSocket(STATESV_IP_ADDR, S_STATE,0);  //스테이트 서버와 연결

 Pack->Send(sock_State);

 closesocket(sock_State);
}

'API & MFC > 네트워크프로그래밍' 카테고리의 다른 글

EventSelect란?  (0) 2010.02.05
ASyncSelect 예제  (1) 2010.02.04
소켓통신의 라이브러리 사용 선택 시 고려사항  (0) 2010.02.02
소켓통신(함수정리)  (1) 2010.01.18
OSI 모델 And Ip계층  (0) 2010.01.18
Posted by 아몰라
이전버튼 1 이전버튼