비동기 소켓이란.

 

동 기 : 소켓이 서로 통신할 때 데이터를 언제 보낼 것인가와 언제 받을 것인가를

알고 있는 경우의 통신. 만약 데이터를 보냈는데 받지 못하는 상황이 발생

하거나 데이터를 받을 준비를 했는데 아무것도 오지 않는 상황이 발생한다면

이로 인해 프로그램이 멈추게 된다. 언제 데이터가 오고 가는지 알고 있어야만

통신이 가능해진다.

비동기 : 서로 통신할 시기를 알지 못하는 경우를 생각해보면 언제 올지 모르는 데이터를

계속 기다리는 것은 비효율적인 작동방식이 된다. 이를 효율적으로 작동시키기 위

해서는 언제 데이터가 오는지는 알 필요 없이 데이터가 왔는지 안 왔는지만 확인해

서 다른 작업을 하다가 데이터가 왔다면 그 때 도착한 데이터를 받아 들인 후 처리

하면 된다.

 

블러킹모드와 넌블러킹모드

 

블러킹모드 : 소켓은 기본적으로 socket()함수를 써서 소켓을 생성하게 되면 블러킹모드로

만들어지게 된다. 블러킹모드에서 send()나 recv()함수를 호출하게 되면 데이

터가 가거나 오지 않는 이상 이 함수는 리턴을 하지 않고 계속 머무르게 되어

있다.

넌블러킹모드: fcntl()함수를 이용하여 소켓을 넌블러킹모드로 만들 수 있다. 이렇게 해서 만

들 경우 소켓은 데이터를 보내거나 받을 시 데이터가 있으면 바로 보내거나

받게 되고 없다면 errno변수(errno.h 헤더에 있다)에 상태를 기록하게 된다.

이 상태변수를 보고 무엇을 할지 결정하면 된다.

 

함수의 블록상태와 넌블럭상태

함수를 호출했을 때 리턴이 되지 않고 어떠한 상태가 될 때까지 무한히 기다리게 되는 경우가 있게되면 이것은 블록킹함수이고 이러한 상태가 없이 어떤 결과든 리턴해주게되는 경우가 넌블럭킹함수이다.

 

 

 

비동기의 방식

 

블록과 넌블록함수는 프로그램의 상태를 말해주는 의미이고 동기와 비동기는 읽기와 쓰기의 상태에 때라 구별되는 개념이다. 동기란 입력과 출력의 상호간에 약속에 의해 동시간에 이루어지는 것이다. 즉 A라는 상대가 1시에 파일을 보내기로 했다면 이것을 받는 B라는 상대도 1시에 정확히 파일을 받는 것을 의미한다. 만약 B가 1시 이전부터 파일을 받으려고 한다면 1시까지는 기다려야 함을 의미하며 B가 1시에 기다리고 있는데 A가 보내지 않는 다면 B는 A가 보낼 때까지 기다려야 함을 의미한다. 비동기는 언제 보내고 언제 받을지를 결정하지 않고 상대가 보낸다는 신호를 받으면 그 때 받는 행동을 하는 것이다. 비동기의 예를 들면 전화나 편지가 있다. 상대가 언제 보낼지 알 수 없고 전화벨이 울리면 그 때 받으면 된다. 전화벨이 울리기 전까지는 다른 일을 해도 된다.

 

비동기의 방식에는 여러가지가 있는데 윈도우와 유닉스의 방식에는 같이 쓸 수 있는 방법이

select()함수를 이용한 방법이 있다. 그리고 윈도우에서 지원해주는 여러가지 함수를 이용해서 다양한 방법을 쓸 수 있다. 리눅스에서는 select()나 poll()함수를 이용하여 만들 수 있는데 이 방법은 엄밀히 말하면 비동기가 아니다. 단지 운영체제가 언제 recv나 send함수를 호출해야 하는 지를 가르쳐주기 때문에 통신은 동기로 이루어 지지만 방식은 비동기에 가깝다. 진정한 비동기 방식은 운영체제에서 프로그램에 인터럽트를 걸고 데이터가 왔다고 알린 후 콜백함수를 등록하여 이를 호출하여 처리되는 식으로 동작할 것이다. 하지만 이런 방식은 구현이 까다롭고 OS에 대해 잘 알고 있어야 하며 select나 poll 방식에 비해 효율적이라고 할 수도 없어서 대부분 다른 방식을 사용한다고 한다.

이런 방식으로 SIGNAL 방식이 있다. 이것은 운영체제에 어떠한 신호를 등록해두고 자신은 다른 일을 하다가 신호가 오면 운영체제가 신호를 받아서 미리 등록해둔 방식으로 동작하도록 하는 것이다. 이 방식은 쓰레드를 써야하며 멀티플렉싱이 이루어 져야 할 때는 모든 소켓을 뒤져야 하므로 poll이나 select 방식에 비해 장점이 없다. 이러한 단점을 극복한 방법으로 REALTIME SIGNAL이라는 방법이 있지만 구현이 까다롭다고 한다.

 

 

 

다중 비동기 소켓 클래스

 

poll방식을 사용하여 비동기방식으로 다중 소켓을 처리할 수 있는 소켓클래스이다.

http://www.joinc.co.kr/modules/moniwiki/wiki.php/%BA%F1%B5%BF%B1%E2%BC%D2%C4%CF%BC%AD%B9%F6%C5%AC%B7%A1%BD%BA

이곳에서 구현해놓은 클래스와 예제가 있어서 분석해보았다.

 

파일 리스트를 보면

sock.h // sock클래스 구현 socket의 기본 기능을 구현

sock.cpp

asyncSocket.h // 다중 비동기 통신을 위하여 AsyncSocket클래스 구현

asyncSocket.cpp

log.h // 에러 보고를 위한 함수 선언 헤더

log.cpp

이렇게 있다.

 

Sock 클래스

 

소켓의 기본 기능인 connect나 bind, send등의 함수를 구현해 놓은 클래스이다.

특이점은 처음 connect를 할 때 블러킹되는 것을 방지하기 위하여 fcntl함수를 이용하여

소켓을 넌블러킹모드로 만들었다가 다시 블러킹으로 바꿔준다는 것이다.

그외에는 소켓의 기본 기능이 모두 들어가 있다.

 

AsyncSocket 클래스

 

다중접속을 위해 만들어진 소켓클래스이다. 소켓을 얼마나 열지는 클래스 생성자의 인자를 이용해 줄 수 있다. 언제나 0번 소켓은 서버용으로 사용되고 입력을 받는데 사용된다.

그외의 소켓은 accept함수에서 지정해주는 소켓을 받아서 통신에 사용하게 된다.

 

AsyncSocket클래스는 Sock클래스에서 상속을 받지 않고 다중소켓을 만들기 위하여 Sock개체를 포함하여 다수의 Sock객체를 가지고 있다. poll()함수를 사용하는 함수이기 때문에

apoll() 메소드가 가장 중요한 부분이 된다.

중요한 속성변수로

struct polldf* pFd;

ConInfo* conSock;

Sock * sock;

이 있다. pFd 는 poll함수에서 사용하기 위한 변수로 자세한 설명은

http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/Network_Programing/Documents/Poll

이곳에서 참고하였다.

ConInfo* conSock; 이 변수는 socket의 상태를 저장하기 위한 변수이다. 이것을 보고 현재

소켓이 접속되었는지 아닌지를 판단하게 된다.

poll함수는 pollfd형 포인터로 여러 개의 pollfd구조체변수를 등록해서 이 중에 어떤 소켓에

입력이나 출력등의 신호가 왔는지를 판단해 주게 된다.

 

 

 

이 AsyncSocket클래스는 예제가 있어 사용하기에는 불편함이 없지만 TCP에 국한되어있고

사용하는데 불편한 점이 있어서 직접 클래스를 작성하기로 하였다.

 

select방식의 비동기 입출력

 

select 방식의 소켓의 방식을 알기 위해 www.sourceforge.net 에서 찾아보았다.

Asynchronous Socket Library로 검색하면 나오게 되는 예제소스가 있는데

Select의 동작방식은 알 수 있었지만 클래스단위로 구현되어 있지 않고 전역함수를 사용하는 등의 방식으로 이루어져 있어서 사용하기에 까다로워 보였다. 그래서 새로 하나 만들어보기로 했다.

우선 새로 만든 클래스는 소켓의 기본적인 역할을 하는 클래스와 이를 이용해서 비동기로 작동하게 하는 클래스를 만들었다.

 

기본 소켓 클래스

CSocket

이 클래스는 소켓이 할 수 있는 대부분의 동작을 메소드로 구현해 두었으며 이 클래스만 가지고 통신을 할 수 있게 만들었다.

생성자의 인자를 이용해 TCP나 UDP로 이용할 수 있게 만들어 두었다.

클래스 헤더는 다음과 같다.

 

#ifndef _CSOCKET_H_

#define _CSOCKET_H_

 

typedef int SOCKET;

 

class CSocket

{

private:

SOCKET m_sockfd;

short m_port;

uint m_ip;

int m_family ; //AF_INET

int m_type; //SOCK_STREAM or SOCK_DGRAM

int flag;

sockaddr_in m_addr;

static socklen_t m_addrlen;

sockaddr_in m_client_addr;

static socklen_t m_clientlen;

 

bool isNonBlock;

 

public:

 

CSocket();

CSocket(int family,int type,int protocol);

~CSocket();

int Send(char * buf,int length,int flag=0);

int Sendto(char * buf,int length,sockaddr* addr,socklen_t len);

int Recv(char * buf,int length,int flag=0);

int Recvfrom(char * buf,int length,sockaddr* addr,socklen_t* len);

int Bind(void);

int Connect(int retry);

int Listen(int backlog=5);

int Accept(int srvfd);

int Close();

int setToBroadcast();

int setSockOpt(int level, int optname, const void *optval, socklen_t optlen);

int setNonBlockSock();

int setaddr(const char* ip, int port);

int setsvraddr(const char* ip, int port);

int setSocket(int family, int type, int protocol);

int setSockfd(int fd);

int getfd();

 

};

 

#endif //_CSOCKET_H_

CAsyncSock

 

CSocket클래스 객체를 포함하는 클래스이다. 상속을 사용하지 않은 이유는 CAsyncSock클래스는 다중접속을 위한 클래스이고 CSocket클래스는 하나의 소켓만 고려한 클래스이기 때문에 상속을 받기에는 부적합하기 때문이다.

다음은 CAsyncSock의 클래스 선언부이다.

 

class CAsyncSock

{

private:

 

vector <int> fds;

vector<ConInfo> m_sockinfo;

int maxi;

int conNum;

fd_set read_fds, write_fds;

 

public:

CAsyncSock();

CAsyncSock(int maxNum

virtual ~CAsyncSock();

int Close(int i);

locker < vector <CSocket > > m_sockList; //socket array

void InitAsync();

int aListen(int domain, int type, int protocol, const char* ip, int port, int backlog);

int aConnect(int domain, int type, int protocol, const char* ip, int port, int retry, int t) ;

void AsyncNotificationLoop(bool noWrites=false);

unsigned int GetAvailBytes(int i);

int getconNum(void);

int getSockStatus(int i) ;

void increaseSock(int i, bool increase);

void Select(timeval *timeout, bool noWrites);

virtual int OnRead(int i);

virtual int OnWrite(int i);

virtual int OnClose(int i);

};

locker<> 클래스는 템플릿 인자를 상속받아서 만들어지는 클래스로 작업도중 뮤텍스락을 걸수 있도록 해서 못건드리도록 하는 작업을 하는 클래스이다.

 

Select함수를 이용했기 때문에 select메소드에서만 입력에 대해 확인하고 대응되는 동작은

OnRead나 OnClose함수를 재정의해서 사용하면 된다.

저작자 표시
신고

'기타 > 기술문서' 카테고리의 다른 글

비동기 통신 학습  (0) 2011.12.14
visual assist 설정 및 단축키 설명서  (0) 2009.12.20
DB 연결샘플  (0) 2009.12.20
WCF 정리  (0) 2009.12.17
C# 패턴  (0) 2009.12.17
AVR_GCC 닷넷에서 사용하는 방법.  (0) 2009.12.17
Open API 관련 정보 기타 2011.05.13 13:41

참고사이트

네이트

네이버

다음

KT(전화) OPEN API

야후

Google 코드 사이트

me2day

트위터

토씨 (링크제공 트위터 @cleanblue)

스프링노트

동영상관련

쇼핑몰

기타 오픈 API

 

참고자료

 
sitehis.com 관련 게시물



저작자 표시
신고

'기타' 카테고리의 다른 글

Open API 관련 정보  (0) 2011.05.13
애드젯(adget)으로 광고수익을 얻어보자.  (0) 2011.03.30
실전 현장에서...  (0) 2010.06.13
프로그래밍은 상상이다  (0) 2010.06.13
ASP.NET 책을 보면서  (0) 2010.04.21

광고주 -> 애드젯<-> 광고회원
포인트는 노출수, 클릭수, 상품팔림으로 벌어들이는 수입원~

지금 바로 가입하세요~~~


저작자 표시
신고

'기타' 카테고리의 다른 글

Open API 관련 정보  (0) 2011.05.13
애드젯(adget)으로 광고수익을 얻어보자.  (0) 2011.03.30
실전 현장에서...  (0) 2010.06.13
프로그래밍은 상상이다  (0) 2010.06.13
ASP.NET 책을 보면서  (0) 2010.04.21
간만에 툴 설명이다~ 뭐 한글은 한국에서 한글작업을 위한 대표적인 툴이지 않는가 ㅎㅎ
일단 처음에 설치하고 나서 조금 로딩이 있어 아 왜이렇게 오래 걸리지 하면서 짜증이 났지만 처음설치때만 그렇지 2007보다는 상당히 빨리 실행되는것같아 시작은 만족하다.


위 그림은 한글 2010을 처음 킨 화면이다. 오피스2007을 사용해본 사용자들은 왠지 오피스 필이 난다는 사실을 한눈에 볼 수 있다. 뭐 큼지막 해서 좋긴 하다 ㅎㅎ


표를 만든 화면이다. 한글2007까지만해도 이렇게 자동으로 표를 꾸며주는 기능이 존재하지 않아서 굉장히 불편한 감이 없지 않았지만 이번에 새롭게 추가되어~ 정말 좋다~~ 비록 잘 쓰진 않지만 말이다.

또 무슨 기능들이 있을까 해서 찾아보니 그림효과 기능들이 좋아진것 같다~


다음과 같이 생그림도 위와같이 편집하면 클릭 몇방으로 프로같이 반사기능, 네온, 옅은 테두리 같은 액자 기능도 만들수 있고, 스타일도 쉽게 줄수가 있다. 정말 좋다~ ㅎㅎ 훈훈하다. 이렇게 한글이 좋아지니 기존에도 한글로 거의 문서편집 작업을 했으나 더욱더 보강되서 완전 더 쓰게 되겠구나 라는 생각이 든다.

또 다른 기능을 보자면 우측에 보면 자르기 기능인데 이 기능은 정말 오피스에서 가지고 오고 싶었다. 자르기 기능이 없어서 워드가서 작업할때도 많이 있었는데 이제 그런 수작업을 할 필요가 없으니 한결 수월해 질 것 같다.

정말 유용한 기능들이 많지 않은가? ㅎㅎ 어떤것들이 있는지 또 찾아보자. 오 노~~ 블러그 관리도 이제 한글에서 척척 할수 있겠군.


정말 득이 되는 기능들이 많이 추가 되었다. 마지막으로 한가지 더 봐보면 편집 화면나누기 기능이다. 책을 만드는 작업을 할 때 유용할 것 같다.



학교에서 한글을 이용하여 책을 만들던 시절에 이런 기능들이 있었으면 좀더 빠르게 생산할 수 있었것만...
아 정말 좋다.

끝으로 이번에 나온 한글은 정말 정품을 사용할것을 권하고 싶다. 기능면이나 편리성이나 인터페이스 부분까지 모두 만족스럽다. 기가막힌 버전이 나온것 같아서 너무 기분이 좋다.
저작자 표시
신고
실전 현장에서... 기타 2010.06.13 23:30
운영체제(operationg systems)를 학습한 사람이라면 멀티 쓰레딩과 관련된 내용을 깊숙히 알고 있겠지만 그렇다고 해도 실전에서 흔히 실수를 범하는 영역은 바로 멀티 쓰레딩과 관련된 부분이다.

굵직한 버그는 항상 멀티 쓰레딩 문제와 관련이 되어 있었다.

모니터를 설명하시오.
대뜸 synchronized라는 키워드를 대답으로 내놓는 사람이 있다.
이런사람은 '하드코어 프로그래머'와 거리가 멀다. 키워드만 알고 원리를 모르는 사람이라고 볼 수 있는 것이다. 이런 사람이 작성하는 코드는 버그를 안고 있다고 보면 거의 틀리지 않는다. 당장은 눈에 뜨이지 않을지 몰라도 사용자의 수가 늘어나면서 시스템의 엔트로피가 상스하면 버그는 어떤식으로든 모습을 드러낸다.

INSIDE THE JAVA VIRTUAL MACHINE
Inside of Java Virtual Machine(McGraw-Hill, 2000) 빌 베너스는 모니터를 세 개의 방으로 이루어진 건물로 묘사했다.
세개의 방이란? 
1. 처음의 들어온 사람이 머무르는 대기실
2. 작업을 수행하는 사람이 있는 작업실
3. 작업을 하는 도중에 잠깐 쉬어야 할 일이 생긴 사람이 들어가서 쉬는 휴게실이다.

이책을 보기 위해 인터넷을 뒤져 보았지만 제목이 조금 틀린것 같아 찾아보니 위에서 진하게 칠한것과 같이 제목이 틀렸다. 꼭 사서 보고 싶지만 원서라서 번역서가 나오기만을 기다려야 한다. 번역된 좋은 책들도 아직도 안본게 수두룩 하니 다음 기회로 미루어 본다.

- 참고문헌 : 프로그래밍은 상상이다.

저작자 표시
신고

'기타' 카테고리의 다른 글

Open API 관련 정보  (0) 2011.05.13
애드젯(adget)으로 광고수익을 얻어보자.  (0) 2011.03.30
실전 현장에서...  (0) 2010.06.13
프로그래밍은 상상이다  (0) 2010.06.13
ASP.NET 책을 보면서  (0) 2010.04.21

책 읽는것을 세상에서 가장 싫어하는 나지만 소프트웨어 개발이나 전공서적과 관련된 책은 꼬박꼬박 읽는다.
"프로그래밍은 상상이다."라는 책도 마찬가지로 소프트웨어 개발과 관련된 서적이다.
그중 재밌는 제목들이 눈에 들어와서 정리해 보려고 한다.
첫번째로
'인기 프로그래밍 언어 50'
10년전인가 대학을 막 입학했을 당시 어떤 프로그래밍 언어를 공부하면 살아남을 수 있을까 하면서 고민했던 시절이 문뜩 떠오른다. 만약 이책을 그때당시에 읽었더라면 난 지금보다 더 뛰어난 프로그래밍 예술가가 되었을텐데 말이다. 이책에 장점은 이런 프로그래머들에게 심정을 허심탄하게 말해주는것 같아서 더 쭉쭉 읽어 나갈수 있었던거 같다. 다음의 글귀를 보자

 "생존의 절박함이 등을 떠밀지 않는 한 프로그래머는 언어를 바꾸지 않는 것이다. 그렇기 때문인지 그들은 결코 자기가 선택한 언러를 단순히 여러 개의 언어 중 하나에 불과하다고 생각하지 않는다. 자신이 선택한 언어는 항상 최선의 언어이다. '우연'이 아니라 '필연'의 결과인 것이다. 많은 프로그래머에게 언어가 단순히 기술적인 의미에 머무르지 않고, 정치적, 도덕적, 심지어 종교적 차원의 의미를 갖는 것은 이러한 까닥에 연유한다."

꽤 글귀가 글다. 적다 보니... 읽을때는 별로 안길었는데 말이다. 그렇다. 우리는 자신의 선택한 언어가 운명적이라고 생각하지 않고 그 당시에 가장 유망있고, 이것만 하면 먹고살 수 있을꺼야 라는 생각으로 배워서 그 언어에 대해서 합리화 시키는 경우가 허다했을 것이다. 나또한 그랬으니 말이다. 본인도 대학시절 C언어보다 VB를 더욱 선호했다. VB는 쉽고 생산성이 좋아서 배우기 쉬웠을뿐만 아니라 내가 일하려는 회사에서도 중점적으로 다루었던 언어였기에 난 필연적으로 배우고 익혔던거 같다. 그때당시만 해도 왜 타언어를 배워야 하는지 이유를 알 수 없었다. 하지만 점점 세월이 지나고 내공이 쌓여 갈수록 프로그래밍 언어는 필요에 따라서 그때그때 변경되는것을 알 수 있었다. 대학시절 각종 언어를 이것저것 배운다. C, C++, 자바 등등... 그때는 왜 이렇게 이것저것 배울까 라는 생각이 들었지만, 그때당시에 조금이나마 배워났던 지식들을 다시 꺼내 쓰는 경우도 많았던것 같다. 말이 너무 샌거 같다. 이책에서 재밌는 사이트를 갈켜주었는데 여러분도 가서 확인해 보기 바란다.

http://www.tiobe.com/tpci.htm

아는 분도 있겠지만 이 재밌는 사이트는 세계에서 인기있는 언어들을 순위를 매겨 보여준다. 내가 사용하는 언어는 몇위인지 알고, 점유율은 어떻게 되는지 대해서 보고 싶은 분들은 한번가서 확인해 보는것도 재밌을 것 같다.

본내용은 "프로그래밍 상상이다."에 저작권이 있습을 알림니다.

저작자 표시
신고

'기타' 카테고리의 다른 글

Open API 관련 정보  (0) 2011.05.13
애드젯(adget)으로 광고수익을 얻어보자.  (0) 2011.03.30
실전 현장에서...  (0) 2010.06.13
프로그래밍은 상상이다  (0) 2010.06.13
ASP.NET 책을 보면서  (0) 2010.04.21
ASP.NET 책을 보면서 기타 2010.04.21 01:12

여러분께 다시 한번 당부드릴 것은 만약 해도해도 이해가 안 되는 부분이 있으면 그냥 흘려버리고 다음 내용으로 넘어가라는 것입니다.

하지만 현재 실무에 있는 많은 개발자 분들도 이렇게 공부했으며, 이렇게 함으로써 포기하지 않고 계속 공부해 나갈 수 있는 것입니다.

이해가 안됐던 부분은 해당 분야에 익숙해지고, 뒤에 나오는 부분을 섭렵하다 보면 저절로 이해가 되는 경우가 다반사 입니다.

필자가 우려하는 것은 여러분이 나무에 붙은 잎의 잎맥과 솜털이 보이지 않는다고 해서 전체적인 숲을 보는 것을 포기하는 것입니다.

만약 여러분이 이 책이 이끌어 주는 대로 끈기를 가지고 공부하여 이 책을 마스터하게 되면 여러분은 최소한 ASP.NET 2.0의 전체적인 숲을

볼 수 있으며 중급으로 나아가기 위한 초석을 마련할 수 있을 것입니다.

신고

'기타' 카테고리의 다른 글

Open API 관련 정보  (0) 2011.05.13
애드젯(adget)으로 광고수익을 얻어보자.  (0) 2011.03.30
실전 현장에서...  (0) 2010.06.13
프로그래밍은 상상이다  (0) 2010.06.13
ASP.NET 책을 보면서  (0) 2010.04.21


mfc, c++ 제작시 유용한 툴
저작자 표시
신고

'기타 > 기술문서' 카테고리의 다른 글

비동기 통신 학습  (0) 2011.12.14
visual assist 설정 및 단축키 설명서  (0) 2009.12.20
DB 연결샘플  (0) 2009.12.20
WCF 정리  (0) 2009.12.17
C# 패턴  (0) 2009.12.17
AVR_GCC 닷넷에서 사용하는 방법.  (0) 2009.12.17

저작자 표시
신고

'기타 > 기술문서' 카테고리의 다른 글

비동기 통신 학습  (0) 2011.12.14
visual assist 설정 및 단축키 설명서  (0) 2009.12.20
DB 연결샘플  (0) 2009.12.20
WCF 정리  (0) 2009.12.17
C# 패턴  (0) 2009.12.17
AVR_GCC 닷넷에서 사용하는 방법.  (0) 2009.12.17
WCF 정리 기타/기술문서 2009.12.17 03:18

Windows Communication Foundation를 정리한 자료


저작자 표시
신고

'기타 > 기술문서' 카테고리의 다른 글

visual assist 설정 및 단축키 설명서  (0) 2009.12.20
DB 연결샘플  (0) 2009.12.20
WCF 정리  (0) 2009.12.17
C# 패턴  (0) 2009.12.17
AVR_GCC 닷넷에서 사용하는 방법.  (0) 2009.12.17
사용자 메시지 구현하기.  (0) 2009.12.17
WCF