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.02.02
소켓함수 예제(로그인서버)  (0) 2010.01.25
소켓통신(함수정리)  (1) 2010.01.18
OSI 모델 And Ip계층  (0) 2010.01.18
Posted by 아몰라

댓글을 달아 주세요

1. 스케줄러

2. MMU 메모리 매핑 유닛

3. Interrupt 관리  - 하드웨어 관리

App > Shell > O/S > Kernel

O/S(Kernel) - 컴퓨터 시스템의 핵이다.


4. NetWork

'API & MFC > API & 시스템프로그래밍' 카테고리의 다른 글

WM_USER And WM_APP  (0) 2010.02.02
레지스트리  (0) 2010.02.02
o/s의 role  (0) 2010.01.28
파일매핑예제  (0) 2010.01.25
WNDCLASS 구조체  (0) 2010.01.25
스레드의 함정  (0) 2010.01.25
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
소켓함수 예제(로그인서버)  (0) 2010.01.25
소켓통신(함수정리)  (1) 2010.01.18
OSI 모델 And Ip계층  (0) 2010.01.18
Posted by 아몰라

댓글을 달아 주세요