2012. 8. 17. 10:53


ILedService.h


서버1.cpp


서버2.cpp


클라이언트1.cpp


클라이언트2.cpp


클라이언트3.cpp


위파일들은 헤더를 기준으로 서버1 -> 에서 좀더 객체지향적인 서버 2가 완성되었고

클라이언트도 1-> 2 -> 3 순서로 수정되어 같은 역할을 하는 것을 좀더 OCL 에 맞추어 개발하는 방향이다.

완성코드는 아래와 같다.


========================================== [ Server ]=================================================


#include<Windows.h>

#include<iostream>

#include<conio.h>


using namespace std;

void binder_loop(void (*handler)(int,int ,int))

{


//여기서 바인더 드라이버를 Open 해서 Client 에서 오는 event를 대기합니다.

//우리는 윈도우 메세지로 흉내 내도록 하겟습니다.

while(1)

{

MSG msg;

GetMessage(&msg,0,0,0);

handler(msg.message,msg.wParam,msg.lParam);


}

}


//---------------------------------------------------------

void Ontransact(int code, int param1, int param2)

{

switch(code)

{

case 5: cout << "LED ON" <<endl; break;

case 6: cout << "LED OFF" << endl; break;

}

}


DWORD __stdcall ServerMain(void *)

{

cout << "서버시작"<< endl;

binder_loop(Ontransact);

return 0;


}

================================== [ Client ] ===================================================

#include<Windows.h>

#include<iostream>

#include<conio.h>

#include "ILedService.h"


using namespace std;


DWORD ServerID=0;


DWORD __stdcall ServerMain(void *);

//---------------------------------------------------------------

//안드로이드가 제공해주느 함수 부분

void binder_call(int code, int param1, int param2)

{


PostThreadMessage(ServerID,code,param1,param2);


}


class IBinder

{

public:

void transact(int code, int param1, int param2){

binder_call(code,param1, param2);


}

};

//서비스 이름을 인자로 받아서 해당 서비스와 통신하기 위한 바인더를 만들어주는 

//함수


IBinder * getService(char *name )

{

//드라이버를 오픈해서 통신할 수 있는 바인더를 만들어 리턴

return new IBinder;

}

class BpRefBase

{

private :

IBinder *mRemote;

public :


BpRefBase(IBinder *p) : mRemote(p) {}

IBinder * remote() { return mRemote;}


};

//proxy 제작시 - 다중 상속을 단일 상속화 한다.

template<typename INTERFACE>

class BpInterface : public INTERFACE ,public BpRefBase

{

public :

BpInterface(IBinder *p) : BpRefBase(p){} //주의!

};


template<typename INTERFACE> INTERFACE * interface_cast(IBinder *p){

return INTERFACE::asInterface(p);


}


//--------------------안드로이드 제공소스 끝 ---------------------------------

// 이제 바인더를 바로 사용하지 말고 함수 호출처럼 변경하는 클래스를 제공합니다

//

//Proxy : 함수 호출 -> RPC 코드 변경 하는 역할.

//

class BpLedService : public BpInterface<ILedService>

{

public :


BpLedService(IBinder * p) : BpInterface<ILedService>(p){}


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

// void LedOn(){remote()->transact(5,0,0);}

// void LedOff(){remote()->transact(6,0,0);}

// 위의 경우는 어느게 ledOn인자 LedOFF인지 숫자를 외워야한다...

// 때문에 pLed를 만든다

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

void LedOn(){remote()->transact(5,0,0);}

void LedOff(){remote()->transact(6,0,0);}

};


//이제 proxy 제작자는 proxy 클래스를 제공한후 반드시 asInterface 구현부를 

// 제공하기로 약속 한다.

//

ILedService * ILedService ::asInterface(IBinder *svc){

return new BpLedService(svc);

}

void ClientMain(){


IBinder * svc = getService("LedService");

//이제 바인더를 바로 사용하지 말고 __ 로 변경해서 사용합니다.

//BpLedService *pLed = new BpLedService(svc); //강한 결합

//ILedService * pLed = ILedService::asInterface(svc);//약한 결합


ILedService * pLed = interface_cast<ILedService>(svc); // 약한결합을 간지나게 바꿈 

//바인더를받아 스테틱 캐스팅느낌으로...(사실은 프락시)



while(1)

{

// getch(); svc->transact(5,0,0);

// getch(); svc->transact(6,0,0);

getch(); pLed->LedOn();

getch(); pLed->LedOff();

}


}


int main()

{

CreateThread(0,0,ServerMain,0,0,&ServerID);

Sleep(1000);

ClientMain();

getch();

}




Posted by k1rha