범용 소켓 클래스 만들기.

Slides:



Advertisements
Similar presentations
프로젝트 보고서 학과 : 임학과 학번 : 성명 : 조성환 Windows 프로그래밍.
Advertisements

Oozie Web API 기능 테스트 이승엽.
DB 프로그래밍 학기.
DB 프로그래밍 학기.
Socket Programming 소개.
WSAAsync Select 김대열 Bit - Academy Sunmoon University, Korea.
Lecture 2 MFC and Application Frameworks
Lab 10 Guide: 프린터 출력 예제. 한 페이지의 그림 인쇄 (교재 24장, 쪽)
10장. 소켓 입출력 모델(I) 블로킹과 넌블로킹 소켓의 특징을 이해한다. Select 소켓 입출력 모델을 이해하고 활용한다.
Chapter 09. 소켓 입출력 모델(I).
Network Socket Programming
인공지능실험실 석사 2학기 이희재 TCP/IP Socket Programming… 제 11장 프로세스간 통신 인공지능실험실 석사 2학기 이희재
Ch.07-5 xml-rpc 사용하기 김상엽.
Network Lab. Young-Chul Hwang
윤 홍 란 다이알로그(대화상자) 윤 홍 란
윤 홍 란 MFC 기초 윤 홍 란
소켓 모델 주소 지정 in_addr_t inet_addr(const char *ip_address) 연결 지향 모델 (TCP)
Department of Computer Engineering
한남대학교 컴퓨터공학과 컴퓨터 네트워크 실험실
Department of Computer Engineering
인공지능실험실 석사 2학기 이희재 TCP/IP Socket Programming… 제 7장 소켓 연결의 우아한 종료 인공지능실험실 석사 2학기 이희재
Linux서버를 이용한 채팅프로그램 지도 교수님 : 이형원 교수님 이 름 : 이 은 영 학 번 :
네트워크 프로그래밍 Yang-Sae Moon Department of Computer Science
Chapter 21 Network Layer: ARP, ICMP (IGMP).
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
Chapter 06. UDP 서버/클라이언트.
인공지능실험실 박사 1학기 장성만 TCP/IP Socket Programming… 9장 소켓의 다양한 옵션 인공지능실험실 박사 1학기 장성만
NJM Messenger 박상원 박연호.
01. DHCP의 개념 조직의 네트워크에 연결되어 있는 워크스테이션의 TCP/IP 설정을 자동화하기 위한 표준 프로토콜
메시지 큐[5] – test1.c 메시지 제어: msgctl(2) #include <sys/msg.h>
ARP Project 조 충 호 교수님 김 세 진 조교님 조 진 형 변 익 수
프로젝트 발표 순서 12/7(수), 팀 별 15분 발표순서 PPT (팀 별 이름, 구현 내용, 결과-그래프 포함) 각 기법당
Department of Computer Science and Engineering
13장 고급 입출력 함수 박사 4학기 최 성자.
TCP/IP Socket Programming…
Socket Address Structure and Byte Ordering Functions
분할 윈도, 다중 뷰… 영상 통신 연구실 권 동 진 발표 일 : 04월 27일.
Chapter 5 UDP Socket 소켓 프로그래밍.
13. 연산자 오버로딩.
I/O&socket통신 POWERPOINT & GROUP STUDY 한재희 김상훈 최기람 황인준 이어진.
사용자 함수 사용하기 함수 함수 정의 프로그램에서 특정한 기능을 수행하도록 만든 하나의 단위 작업
Chapter 09. 소켓 입출력 모델(I).
영상처리 실습 인공지능연구실.
Lab 1 Guide: 교재 2장 DrawX ( 쪽)
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
WSAAsync Select 김대열 Bit - Academy Sunmoon University, Korea.
PC에 설치된 엔드포인트 클라이언트 프로그램을 클릭하여 프로그램 상자를 엽니다
컴퓨터 프로그래밍 기초 - 10th : 포인터 및 구조체 -
Network Programming - 최종보고서 -
Department of Computer Engineering
Lab 9 Guide: 인터넷 프로그래밍 예제 * 일대일 채팅 프로그램 (교재 27장, 쪽)
Lab 8 Guide: 멀티스레딩 예제 2 * Critical Section을 이용한 멀티스레딩 동기화 (교재 15장, 쪽)
컴퓨터 프로그래밍 기초 - 8th : 함수와 변수 / 배열 -
컴퓨터 계측 및 실습 디지털 출력 영남대학교 기계공학부.
12. 상속 : 고급.
프로젝트 제안서 -TCP/IP를 이용한 메신저 구현-
01. DHCP의 개념 조직의 네트워크에 연결되어 있는 워크스테이션의 TCP/IP 설정을 자동화하기 위한 표준 프로토콜
3. 윈도우 핸들 제어.
12강. 컨트롤러 컨트롤러 클래스 제작 요청 처리 메소드 제작 뷰에 데이터 전달
Chapter 27 Mobile IP.
Chapter 04. TCP 서버/클라이언트.
가장 많이 사용 Accelerator 최상위 WM_COMMAND, OLE 메시지 관련 이벤트 처리만 가능 이 클래스를 상속받아서 다른 이벤트 처리 이벤트 처리 관련 윈도우(창) 최상위 클래스 멀티 테스킹(모듈) CFrameWnd, Cview,
3. 모듈 (5장. 모듈).
다자간 채팅프로그램 김형도 허영민
실습 UBLAB.
Network Lab. Young-Chul Hwang
29장. 템플릿과 STL 01_ 템플릿 02_ STL.
Completion Port기반의 채팅프로그램
MFC 기초 윈도우 응용프로그램 개발 간략한 역사 Microsoft Foundation Classes
중간 결과 보고 ( Server & Client )
Presentation transcript:

범용 소켓 클래스 만들기

Contents 예제 서버 클라이언트 채팅 소스 분석 및 관련 API Overview

Overview of MS .NET

MFC Library

Classical Win32 API Programming Use C to access raw API functions directly No C++ class library wrappers to hide API Hard way to go, but most basic Faster executables Provides understanding of how Windows and application program interact Establishes a firm foundation for MFC programming

MFC Library Microsoft’s C++ Interface to Windows API O-O Approach to Windows Programming Some 200 classes API functions encapsulated in the MFC Classes derived from MFC do grunt work Just add data/functions to customize app Provides a uniform application framework

The Event-Driven Paradigm

CASyncSocket을 상속받아 만들기 서버클래스 클라이언트클래스 CASyncSocket pSocket pSocket->Create(2000) pSocket->Listen() CAsyncSocket pSocket pSocket->Create(); pSocket->Connect(Adr,2000); pSocket pSocket->Receive(data); pSocket->Send(“나도안녕!”) CASyncSocket Sock pSocket->Accept(Sock) Sock.Send(“안녕”) Sock.Receive(data);

CAsyncSocket의 특정 멤버함수 OnAccept(); 클라이언트가 Connect를 실행하여 서버에 접속하고자 할 때 서버에서는 새로운 클라이언트가 들어오면 OnAccept함수가 실행된다. OnReceive(); 새로운 데이터가 들어왔을 경우에는 OnReceive라는 함수가 실행됨. 즉 새로운 클라이언트가 접속을 실행하면 메시지를 날려주는 것이 아니라 OnAccept()함수가 실행되고 또한 새로운 데이터가 들어왔을때는 OnReceive()함수가 실행됨 CMySocket::public CAsyncSocket{ public: virtual void OnAccept(int nErrorCode); virtual void OnReceive(int nErrorCode); }

서버클래스(CServerSock) #include "client~1.h" #define WM_ACCEPT_SOCKET WM_USER+1 class CSeverSock : public CAsyncSocket { public: CSeverSock(); //메세지를 전달할 HWND설정 void SetWnd(HWND hwnd); //현재 클라이언트와 연결된 소켓을 받는다. CClientSock* GetAcceptSocket(); //새로운 클라이언트가 연결되었을대 virtual void OnAccept( int nErrorCode ); //새로운 클라이언트 가 연결되었을때 //Accept할 소켓 클래스 변수 CClientSock m_pChild; HWND m_pHwnd; }

서버클래스(CServerSock) #include "stdafx.h" #include "sversok.h" //생성자 //새로운 클라이언트가 연결되었을때 //실행되는 함수 void CSeverSock::OnAccept( int nErrorCode ) { TRACE("Errocode = %d",nErrorCode); //클라이언트 클래스인 m_pChild로 연결시켜준다. Accept(m_pChild); //새로운 클라이언트가 연결되었다는 //WM_ACCEPT_SOCKET 메세지를 전달합니다. SendMessage(m_pHwnd,WM_ACCEPT_SOCKET,0,0); } //OnAccept함수 실행후 새로운 클라이언트와 연결된 //m_pChild 소켓을 넘겨줍니다. CClientSock* CSeverSock::GetAcceptSocket() return &m_pChild; #include "stdafx.h" #include "sversok.h" //생성자 CSeverSock::CSeverSock() { CAsyncSocket::CAsyncSocket(); } //메세지를 전달할 윈도우 설정 void CSeverSock::SetWnd(HWND hwnd) m_pHwnd=hwnd;

클라이언트클래스(CClientSock) //clientsok.h //클라이언트용 소켓 프로그램 헤더 #define WM_RECEIVE_DATA WM_USER+2 class CClientSock : public CAsyncSocket { public: CClientSock(); //메세지를 전달할 HWND를 설정하는 함수 void SetWnd(HWND hwnd); //새로운 데이타가 들어왔을대 실행되는 함수 virtual void OnReceive( int nErrorCode ); //메세지를 전달할 HWND HWND m_pHwnd; };

클라이언트클래스(CClientSock) #include "stdafx.h" #include "Clientsok.h" //생성자는 아무일도 안하고 모든생성을 CAsyncSocket에 넘겨줍니다. CClientSock::CClientSock() { CAsyncSocket::CAsyncSocket(); } //데이타가 들어왔을때 현재 hwnd에 새로운 데이타가 들어 //왔다는 메세지를 날려주기위한 hwnd를 설정합니다. void CClientSock::SetWnd(HWND hwnd) m_pHwnd=hwnd; //새로운 데이타가 들어왔을때 현재의 hwnd에 //USER+2인 메세지 WM_RECEIVE를 보냅니다. void CClientSock::OnReceive( int nErrorCode ) TRACE("Errocode = %d",nErrorCode); SendMessage(m_pHwnd,WM_RECEIVE_DATA,0,0);

서버프로그램 만들기 LONG CEx3101View::OnAccept(UINT wParam,LONG lParam) { //새로운 클라이언트와 연결할 소켓을 만들고 m_pChildSock = new CClientSock; //서버 소켓으로부터 현재 연결된 소켓을 받는다. m_pChildSock = m_pSeverSock->GetAcceptSocket(); //hwnd설정 m_pChildSock->SetWnd(this->m_hWnd); char temp[200]; //안녕하세요 라는 데이타를 보낸다. sprintf(temp,"안녕하세요?"); m_pChildSock->Send((LPSTR)temp,200); return TRUE; }

구현하고자 하는 기능 어떤 프로그램에서든 사용 가능한 소켓 클래스를 만든다. 서버 소켓 클래스(CServerSocket) CSocket클래스에서 상속, 서버에서 클라이언트의 접속요청을 받아들이고 데이터 소켓을 연결. 데이터 소켓 클래스(CDataSocket) Csocket 클래스에서 상속, 실제로 데이터를 주고 받는 기능, 클라이언트 소켓으로 서버에 접속 요청. 데이터 구조 클래스(Cdata) 데이터 포맷을 같도록 해준다.

서버프로그램 만들기 void CEx3101View::OnInitialUpdate() { CFormView::OnInitialUpdate(); //서버 소켓을 만든다. m_pSeverSock = new CSeverSock; //서버 소켓의 현재view의 hwnd를 설정한다. //이렇게 설정해놓아야 현 View로 메세지가 전달됨 m_pSeverSock->SetWnd(this->m_hWnd); // 2000번 포트번호로 소켓을 만든다. m_pSeverSock->Create(2000); //클라이언트가 오기를 기다린다. m_pSeverSock->Listen(); } 새로운 클라이언트가 접속했을때 CServerSock은 WM_ACCEPT_SOCKET(WM_USER+1)의 메시지를 발생키시고 이메시지가 발생될 때 실행되는 함수 OnAccept가 있다고 하면 우선 BEGIN_MESSAGE_MAP에 다음과 같이 한다. ON_MESSAGE(WM_ACCEPT_SOCKET, OnAccept) 헤더에는 다음과 같이 한다. afx_msg LONG OnAccept(UINT wParam, LONG lParam)

서버프로그램 만들기 //새로운 데이타가 들어왔을때 LONG CEx3101View::OnReceive(UINT wParam,LONG lParam) { char temp[200]; //소켓으로 부터 데이타를 받은다음 m_pChildSock->Receive((LPSTR)temp,200); //화면과 연결된 m_strReceive에 설정한다. m_strReceive=temp; UpdateData(FALSE); return TRUE; } //데이타 보내기 버튼을 눌렀을때 void CEx3101View::OnSend() UpdateData(TRUE); //에디터에 입력한 데이타를 받아서 lstrcpy((LPSTR)temp,(LPSTR)m_strSend.operator const char*()); //클라이언트에 보낸다. m_pChildSock->Send(temp,200);

클라이언트 프로그램 만들기 LONG CEx3102View::OnReceive(UINT wParam,LONG lParam) { char temp[200]; m_pClientSock->Receive((LPSTR)temp,200); m_strReceive=temp; UpdateData(FALSE); return TRUE; } void CEx3102View::OnSend() UpdateData(TRUE); lstrcpy((LPSTR)temp,(LPSTR)m_strSend.operator const char*()); m_pClientSock->Send(temp,200);

클라이언트 프로그램 만들기 #include "setip.h" void CEx3102View::OnInitialUpdate() { CFormView::OnInitialUpdate(); m_pClientSock=new CClientSock; //IP주소를 묻는 대화상자가 실행된다. CSetIp *pDlg = new CSetIp; if(pDlg->DoModal()==IDOK) char temp[80]; lstrcpy((LPSTR)temp,(LPSTR)pDlg->m_strIp.operator const char*()); //temp 에 입력한 ip주소를 설정한다. m_pClientSock->Create(); //IP 주소와 함께 포트번호 2000을 설정하여 //클라이언트에 접속을 시도한다. m_pClientSock->Connect(temp,2000); //메세지를 받을 HWND설정 m_pClientSock->SetWnd(this->m_hWnd); }

서버소켓 CServerSocket 클래스 만들기 접속 요청이 들어오면 받아들이는 일은 main window에서 수행(범용성 고려) 접속요청이 들어오면 CServerSocket 의 OnAccept가 자동으로 호출 OnAccept -> UM_ACCEPT #define UM_ACCEPT(WM_USER)

CServerSocket #define UM_ACCEPT (WM_USER) class CServerSocket : public CSocket { // Attributes public: // Operations CServerSocket(); virtual ~CServerSocket(); // Overrides void Init(CWnd *pWnd, int nPortNum); CWnd *m_pWnd; // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CServerSocket) virtual void OnAccept(int nErrorCode); void CServerSocket::Init(CWnd *pWnd, int nPortNum) { m_pWnd = pWnd; Create(nPortNum);//소켓 생성 Listen();//접속 요청 감지 } void CServerSocket::OnAccept(int nErrorCode) m_pWnd->SendMessage(UM_ACCEPT); CSocket::OnAccept(nErrorCode);

데이터 소켓 CDataSocket 클래스만들기 실제로 데이터를 송수신 하는 기능 담당 범용성을 위해 새로운 데이터가 수신 되었을때 OnReceive 함수에서 UM_DATARECEIVE메세지를 메인 윈도우에 보냄. #define UM_DATARECEIVE (WM_USER+1) void CDataSocket::OnReceive(int nErrorCode) { m_pWnd->SendMessage(UM_DATARECEIVE); CSocket::OnReceive(nErrorCode); } 송신 : Send, Flush, << 수신 : Receive, >>

CDataSocket Header file class CDataSocket : public CSocket { // Attributes public: CWnd *m_pWnd; CSocketFile *m_pFile; CArchive *m_pArchiveIn; CArchive *m_pArchiveOut; // Operations CDataSocket(); virtual ~CDataSocket(); // Overrides void operator << (CData &data); void operator >> (CData &data); void Flush(); void Send(CData *pData); void Receive(CData *pData); void Init(CWnd *pWnd); // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDataSocket) public: virtual void OnReceive(int ErrorCode); virtual void OnClose(int nErrorCode); //}}AFX_VIRTUAL // Generated message map functions //{{AFX_MSG(CDataSocket) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG // Implementation protected: };

CDataSocket Souce File 데이터소켓 초기화 pWnd : 메시지를 받을 윈도우 데이터 수신용, 송신용 Carchieve void CDataSocket::Init(CWnd *pWnd) { m_pWnd = pWnd; m_pFile = new CSocketFile(this); m_pArchiveIn = new CArchive(m_pFile, CArchive::load); m_pArchiveOut = new CArchive(m_pFile, CArchive::store); } 데이터수신 Carchieve 클래스를 이용하여 Serialize함수를 호출 void CDataSocket::Receive(CData * pData) { if(m_pArchiveIn != NULL) pData->Serialize(*m_pArchiveIn); } void CDataSocket::operator >>(CData & data) Receive (&data);

CDataSocket Souce File 데이터 송신 Serialize 함수를 이용 소켓이 관리하는 송신용 버퍼에 저장만 된다. Flush()사용 void CDataSocket::Send(CData * pData) { if(m_pArchiveOut != NULL) pData->Serialize(*m_pArchiveOut); } void CDataSocket::Flush() m_pArchiveOut->Flush(); void CDataSocket::operator <<(CData & data) Send (&data); Flush(); 마무리 작업 동적으로 할당했던 Carchieve와 CSocketFile 객체를 삭제 void CDataSocket::OnClose(int nErrorCode) { if(m_pFile != NULL) { delete m_pFile; m_pFile = NULL; } if(m_pArchiveIn != NULL) { m_pArchiveIn->Abort(); delete m_pArchiveIn; m_pArchiveIn = NULL; if(m_pArchiveOut != NULL) { m_pArchiveOut->Abort(); delete m_pArchiveOut; m_pArchiveOut = NULL; CSocket::OnClose(nErrorCode);

데이터 구조 CData 클래스 만들기 전송될 데이터는 Cdata 클래스에 캡슐화 문자열 하나를 전송 class CData : public CObject { // Attributes public: // Operations CData(); virtual ~CData(); // Overrides virtual void Serialize(CArchive &ar); CString m_strData; protected: }; void CData::Serialize(CArchive &ar) { if(ar.IsStoring()) // 네트워크로 송신 ar << m_strData; } else // 네트워크에서 수신 ar >> m_strData;

기타 함수들 virtual int Send( const void* lpBuf, int nBufLen, int nFlags = 0 ); 리턴값:송신한 바이트 수 lpBuf: 송신할 데이터가 저장되어 있는 버퍼의 포인터 nBufLen: 송신할 데이터의 바이트 수 nFlag: 이 함수가 호출 되는 방식 virtual int Receive( void* lpBuf, int nBufLen, int nFlags = 0 ); BOOL Listen( int nConnectionBacklog = 5 ); nConnectionBacklog : The maximum length to which the queue of pending connections can grow. Valid range is from 1 to 5. BOOL Connect( LPCTSTR lpszHostAddress, UINT nHostPort ); BOOL Create( UINT nSocketPort = 0, int nSocketType = SOCK_STREAM, long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE, LPCTSTR lpszSocketAddress = NULL );

참조 사이트 http://www.zikimi.co.kr/new_zikimi/z002/002_04.htm?code=37, 지킴이 자료실

Note & Q/A 강의 일정 프로젝트 제안서 제출 ( 2인 1조 ) 프로젝트 최종 보고서 제출 10월 27일 11월 3일 중간고사기간 (10월 17일 ~ 1주간)이후 11월 10일까지(실습 3 진행한 다음주까지) 프로젝트 최종 보고서 제출 12월 1일오후 6시부터 컴퓨터실 공업센타 별관 - PC 2실 611호