[MFC]CSocket 통신

Posted 2008/01/23 23:58 by J2L

기본적인 화면을 구성하였다는 가정하에
아래 코드를 App클래스의 InitInstance()함수에 추가한다

//소켓 초기화
 if (!AfxSocketInit())
 {
  AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
  return FALSE;
 }

 // OLE 라이브러리를 초기화합니다.
 if (!AfxOleInit())
 {
  AfxMessageBox(IDP_OLE_INIT_FAILED);
  return FALSE;
 }

CSocket을 상속받은 클래스를 2개 생성한다.
한개의 소켓은 클라이언트가 접속하기를 대기하면서 연결 시키는 역할이고
한개의 소켓은 클라이언트와 데이터를 주고받는 역할을 한다.
(대기 소켓을 ListenSocket, 실 통신을 하는 소켓을 DataSocket 이라 정의 했다 치자)
ListenSocket의 클래스에 OnAccept()함수를 재정의 한다.
DataSocket의 클래스에는 OnClose()와 OnReceive()한수를 재정의한다.
OnClose()는 접속 종료를 알려주는 함수이고
OnReceive()는 메시지를 받는다는 것을 알려주는 함수이다.

서버 프로그램에서 서버를 초기화 한다.
InitServer(void)
{
 m_pServer = new ListenSocket;
  m_pServer->Create(포트번호);// ??

 m_pServer->Listen();
}

클라이언트 초기화
InitClient()
{
  pSocket =  new Socket();
  if(!pSocket->Create())
 {
  AfxMessageBox(_T("클라이언트 소켓 생성 실패"));
  delete pSocket;
  return false;
 }
  if(!pSocket->Connect(아이피주소,포트번호))
 {
  AfxMessageBox(_T("서버접속실패"));
  pSocket->Close();
  delete pSocket;
  pSocket = NULL;
  return false;
 }
 return true;
}
OnAccept()함수 내에서는 데이타 소켓을 생성해서 클라이언트의 접속을 허용해주고 클라이언트 리스트에 추가해주는 역할을 한다.

EX>
Accept(void)
{
DataSocket* pChild = new DataSocket;

 if(!m_pServer->Accept(*pChild))
   AfxMessageBox("접속 허용 실패");

 m_pSockList.AddTail(pChild);
 CString PeerAddr;
 UINT PeerPort;
 pChild->GetPeerName(PeerAddr, PeerPort);  //IP주소와 포트번호를 알아낸다.
 CString str;
 str.Format("접속 주소: %s, 포트 번호: %d\r\n", PeerAddr, PeerPort);
//로그를 남기고 싶다면 위의 srt변수를 로를 기록하는곳에 넘기면 접속한 클라이언트 정보를 기록한다.
}
OnReceive(){}함수는 데이터를 받는 함수는 클라이언트와 실제 통신을 하는 DataSocket을 이용
데이터를 받는다.
EX>
Receive(DataSocket * pSocket)
{
 DWORD FLAG;
 pSocket->Receive(&FLAG,4);
}

OnClose()함수는 소켓통신의 끝을 알리는 함수이다.
서버측 : 접속 종료된 클라이언트를 찾아서 메모리 해제
SocketClose(DataSocket * pSocket)
{
 DataSocket* pChild;
 POSITION pos = m_pSockList.GetHeadPosition();        
 while( pos !=NULL)
 {
  pChild = (DataSocket *)m_pSockList.GetAt(pos);
  if(pChild == pSocket)
  {
   m_pSockList.RemoveAt(pos);
   CString Log; //로그메시지
   CString PeerAddr; //IP주소
   UINT PeerPort;  //포트번호
   pChild->GetPeerName(PeerAddr,PeerPort);
   Log.Format("%s : %d Disconnect.",PeerAddr,PeerPort);
   //로그파일에 기록하는 위치..
   delete pChild;
   break;
  }
  m_pSockList.GetNext(pos);
 }
}
클라이언트 측 : 서버와의 접속알림
SocketClose()
{
   //서버와 접속이 끊어졌음을 알리는 코드 생성.
}

위에 정의한
코드들은 App클래스에 생성하였으며 해당 코드들을 불러 쓰는 형식을 취하였다.
소켓 클래스에 정의했더
OnAccept 함수에서는 App클래스의 Accept함수를
OnClose함수에서는  App클래스의 SocketClose함수를
OnReceive함수에서는  App클래스의 Receive 함수를 호출하는 형식을 취한다.
인자로 넘기는 DataSocket은 통신하는 클래스가 DataSocket이므로 자신을 인자로 넘겨서
((프로젝트명App*)AfxGetApp())->Receive(this); 이런식으로 호출하면 가능하다.

클라이언트 측에서는 통신하는 소켓이 하나면 되므로 소켓에서 App에 정의한 함수를 호출할때
인자를 넘겨주는 식으로 하지 않아도 된다.

크리에이티브 커먼즈 라이선스
Creative Commons License

'C++' 카테고리의 다른 글

[API] Winsock을 사용한 간단한 계산 통신  (0) 2008/01/30
[MFC] INI File 입출력  (0) 2008/01/29
[MFC]CSocket 통신  (0) 2008/01/23
[MFC]탭컨트롤  (0) 2008/01/22
드라이버 학습에 참고 사이트  (0) 2008/01/21
파일검색 루틴  (0) 2008/01/18

Tag : ,

« PREV : 1 : ... 44 : 45 : 46 : 47 : 48 : 49 : 50 : 51 : 52 : ... 85 : NEXT »