[네트워크 프로그래밍1] 채팅 통신 프로토콜 조사하기(Jabber)

류명운

·

2015. 5. 11. 02:52

반응형


프로토콜조사류명운김형근.hwp


1. 채팅 통신 프로토콜

1. 1 프로토콜(Protocol)이란?

일단, 프로토콜의 정의에 대하여 알아보자면 다음과 같다. "정보기기 사이(컴퓨터끼리 또는 컴퓨터와 단말기 사이 등) 에서 정보교환이 필요한 경우, 이를 원활하게 하게 위하여 정한 여러가지 통신규칙과 방법에 대한 약속 즉, 통신 규약을 의미한다.

이렇듯 프로토콜은 서로 다른 정보기기 사이에서 무언가 통신을 하기 위해 사전에 어떻게 통신할지에 대한 방식을 정해놓은것이라고 생각하면 된다.

1. 2 본 과제에서의 제한 점

정보기기 사이에서는 수 많은 종류의 통신이 이루어지데, 본 과제에서는 채팅을 하면서 이루어지는 통신에 대한 프로토콜을 조사해보는데 제한을 두겠다.

2. 유명한 채팅 프로토콜 조사 및 분석

2. 1 현재 상용되고 있는 유명한 채팅 프로그램 및 사용된 프로토콜 조사

본 절에서는 현재 사용되고 있는 채팅 프로그램 중 나와 형근이가 실제 한 번이라도 사용했던 경험이 있는 채팅 프로그램을 대상으로 각 프로그램에서 채팅이 이루어지기 위해 사용된 프로토콜은 무엇인지 조사해보았다. 이에 대한 결과는 다음 [Table 1]와 같다.

채팅 프로그램

프로토콜 종류

무선문자 메시지

SMS

Buddy Buddy Messenger

확인불가

Window Live Messenger

MSNP

NateOn Messenger

NateOn

Yahoo Chat

YMSG, Jabber(XMPP)

Skype

Skype

Google Talk

VoIP, Jabber(XMPP)

Kakao Talk

LOCO

Facebook Chat

Jabber(XMPP)

Apple iMessage

Jabber(XMPP)

NHN Line

LOCO

Tellegram Messenger

MTProto

2. 2 대표 채팅 프로그램 선출 및 분석

본 절에서는 3. 1에서 알아 본 여러 프로토콜 중 Apple iMessage, Google Talk, AIM, Yahoo Chat, Facebook Chat 등의 여러 채팅 프로그램에서 사용되고 있는 Jabber Protocol(이하 Jabber)에 대하여 살펴보고자 한다.

본 절의 구성은 다음과 같다. 먼저 Jabber의 개요에 대하여 살펴보고, 이러한 Jabber의 구조 및 프로토콜 구현 예를 살펴본다. 그 후 Jabber의 특징 및 장점, Jabber를 실제 사용하여 채팅프로그램을 구현하는 방법에 대하여 살펴보겠다. 마지막으로 Jabber 프로토콜의 향후 전망에 대하여 살펴보는 것으로 본 절을 마치도록 하겠다.

 

2. 2. 1 Jabber 개요

Jabber는 앞서 설명한바와 같이 iMessage, Google Talk, Yahoo Chat, Facebook Chat 등.. 현존하는 대표적인 채팅 프로그램에서 두루 사용되고 있는 XMPP 기반의 오픈 프로토콜이다. 이 XMPP는 2학년 1학기에 배운 OSI 7계층 모델 중 Application에 해당하는 7계층에 속하며, XML을 기반으로 구성되어 인스턴스 메신저들이 갖추어야 할 프로토콜 요소들을 모두 갖추고 있다.

또한 Jabber를 사용하는 서버들간의 통신이 가능하게 지원하여 다른 도메인(Server)을 사용하는 사용자(Client)들과 대화를 가능하게 해준다(ex: Yahoo Chat 사용자와 Facebook Chat 사용자가 대화가 가능). 이렇듯, Jabber를 지원하는 채팅 프로그램의 사용자는 어떠한 공개 Jabber 서버에도 접속할 수 있게 된다. 단, Jabber를 사용하는 Server에서 공개를 해야한다(아쉽게도 Google Talk은 아직 서버를 공개하지 않아 다른 프로그램의 사용자가 접속할 수 없다).

 

2. 2. 2 Jabber 의 구조 및 프로토콜의 예

1) Jabber의 구조

Jabber의 구조는 다음 [Table 2]와 같은 5가지로 분류 할 수 있다.

종류

내용

S1, S2

XMPP 서버

C1, C2, C3

XMPP 클라이언트

G1

XMPP와 외부 메시징 네트워크에서 사용되는 프로토콜들 사이의 게이트웨이

FN1

외부 메시징 네트워크

FC1

외부 메시징 네트워크 클라이언트

 

본 구조를 도식화하면 다음 [Picture 1]과 같다.

보다 간단한 구조로 나타내자면 다음 [Picture 2]와 같다.

- Jabber 메신저 사용자들은 모두 어떠한 Jabber public server에 위치하고 있더라도 다른 server에 있는 사용자와 대화가 가능해 진다.

- 위 클라이언트들은 공개된 Jabber 서버에 계정을 가지고 있는 사용자들이다.

2) Jabber 프로토콜 예

Jabber 프로토콜의 가장 기본적인 예에 대하여 간단히 요약하자면 다음과 같다. Server가 Client에게 자원 바인딩을 요청하라고 알려주면, Client는 서버에게 자원을 할당해달라고 요청을 하는 구조입니다.

간단한 코드를 통해 살펴보도록 하겠다.

Server advertises resource binding feature to client:

<stream:stream

xmlns='jabber:client'

xmlns:stream='http://etherx.jabber.org/streams'

id='c2s_345'

from='example.com'

version='1.0'>

<stream:features>

<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>

</stream:features>

Client asks server to bind a resource:

<iq type='set' id='bind_1'>

<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>

</iq>

2. 2. 3 Jabber 의 특징

Jabber는 인터넷 상의 두 지점 사이에서 메시지와 프레즌스(presence)를 실시간으로 교환하기 위한 오픈 XML 프로토콜이다. Jabber 기술의 첫 번째 어플리케이션은 비동기 적이고, 확장적인 인스턴트 메세징 플랫폼이며 AIM, ICQ, MSN, 야후와 같은 레건시 IM 시스템과 비슷한 기능을 제공하는 IM 네트워크이다.

그러나 Jabber는 레건시 IM 시스템보다는 여러 가지 이점을 제공한다.

 

1) 오픈

Jabber 프로토콜은 자유롭고 열려있고 공개적이며 쉽게 이해할 수 있고 Jabber 서버, 클라이언트 개발 라이브러리를 위하여 여러 가지 오픈소스 구현이 존재한다.

2) 확장성

XML 네임스페이스의 힘을 사용함으로 누구나 Jabber 프로토콜을 커스텀 기능(상호 운영성을 유지하기 위하여 일반적인 확장은 Jabber 소프트웨어 재단이 관리한다) 을 위해 확장할 수 있다.

3) 분산성

누구나 자신만의 Jabber 서버를 운영할 수 있어 개인과 조직이 IM 경험을 제어할 수 있다.

4) 보안

어떤 Jabber 서버는 공공 Jabber 네트워크에서 독립적일 수 있어 많은 서버 구현이 클라이언트/서버 통신을 위해 SSL을 사용하고 수많은 클라이언트가 end-to-end 암호화를 위해 PGP/GPG를 지원한다.

5) 프레즌스(presence)

User 상태라고 보면 된다. 메신저 프로그램에서 메시지를 받을 상대가 접속 중이 아니라면 서버에 저장해둔 뒤 로그인시 메시지를 전송할 수 있다. 예를 들어 설명을 한 것이지만, 이러한 User 상태에 대한 정보를 프레즌스(presence)라 부른다.

6) XML(EXtensible Markup Language)

마크업 언어를 정의하기 위한 언어이다. HTML 이 마크업 언어의 일종이다. HTML 은 웹페이지를 만들기 위한 언어이다. 하지만, 정적인 HTML을 보완하기 위해 ASP 나 PHP 가 사용되게 되었고, 여기서 호환성에 문제가 생긴다. 또한 사이트 개편시 디자인과 내용이 함께 바뀌어야 한다. 디자인만 바뀌는데도 말이다. 이러한 점을 개선하기 위해서 생겨난 것이 SGML 이다. SGML(Standard Generalized Markup Language) 은 표준화된 일반 마크업 언어라 풀이된다. 이는 Meta 언어인데, 쉽게 말해 문서의 다양성을 정의하는 것이다. 더 쉽게 말하자면, 문서가 표현하고 있는 논리적인 구조정보들을 마크업을 이용하여 표현함으로써 정보의 공유와 유통을 극대화시키기 위한 기술적 마크업 언어이다.

즉, SGML은 SW패키지나 SW벤더,HW기종과 관계없이 자료를 저장하고 정보를 교환하기 위한 개념에서 출발하였다. 하지만, SGML 은 너무 덩치가 큰 표준이었고, 사용을 위한 투자비용이 높아 SGML의 많은 부분들을 간소화하고 보완하여 XML 이 탄생하게 되었다. XML 은 내용과 디자인이 완전히 분리되어 있다. 또한, Meta 언어로서 컴퓨터와 사람이 모두 해석할 수 있다.

 

2. 2. 4 Jabber 의 장점

Jabber의 장점

전 세계 Jabber 사용자와 대화가능

구글 토크와 연동가능

인증된 프로토콜사용으로 메신저 신뢰성 향상

기존 메신저와의 차별화 가능

서버 및 클라이언트 라이브러리 제공

서버를 오픈하지 않고 프로토콜만 활용하여 쓸 수 있다.

프로토콜로 인한 문제를 미연에 방지할 수 있다.

XML로 표준화됨으로 타 기능과 연동에 용이하다.

 

2. 2. 5 Jabber를 이용한 채팅프로그램 구현 방법

RFC3921 프로토콜 스펙을 보면 첫장에서 XMPP 메시징 프로토콜은 다음과 같은 사항을 반드시 구현해야 한다고 나온다.

1) Jabber 프로토콜을 사용하려면

- 다른 사람들과 메시지 교환하기

- 다른 사람들과 존재(presence): 여기서의 의미는 누가 로긴했는지, 로그아웃했는지에 대한.. 메시지를 전송하는 기능

- 다른 사람들을 초대하기, 또는 수락하기 기능

- 컨택 리스트 관리 기능(즉 친구리스트 관리기능)

- 특정인을 블록하는 기능

2) Jabber 스키마

- jabber은 아시다시피 xml 프로토콜을 사용한다. 참 그래서 한글이든 모든 인코딩만 바꿔주면 되기 때문에 한글도 지원된다고 할 수 있다.

- 메시지 전송엔 대한 네임스페이스 'jabber:client' , 'jabber:server' 이다.

- 서로 어디서 보냈는지 알려줄때 쓴다.

3) 각각의 스키마 종류

namespace => jabber:client, jabber:server

type => chat(1:1채팅), error(메시지전송에러), groupchat (멀티유저채팅), headline (브로드캐스팅 메시지), normal (일대일 또는 다중채팅 중 보내는 메시지)

<subject/> => 언어 인코딩 설정, xml:lang

<body/> => 읽을 수 있는 메시지

<thread/> => 읽을 수 없는 메시지, 암호화된 코드가 들어가는거 같다.

 

4) Presence의 종류(type)

unavailable : 통신이 불가

subscribe : 수락요청메시지

subscribed : 상대방이 친구요청을 수락했다는 메시지

unsubscribe : 친구를 제거

unsubscribed : 상대방이 친구요청을 거부했다는 메시지

probe : 현재 친구와의 관계가 어떤건지 이미 친구가 나를 차단했다든지

error : 로긴/로그아웃/요청/수락 등의 패킷전송 중 일어날 수 있는 에러

5) Show의 종류(상태설정)

away: 일시적으로 자리비움일때

chat : 채팅중일때

dnd: Busy 일때

xa : 아주 멀리 갔을때 (extended away)

status : 유저의 행동 상태에대한 메시지( 예를들어 미팅중이다. 채팅중이다 란 설명메시지)

priority : -128~127까지 int 형 등급 변수

iq: 구조화된 요청/반응 메카니즘을 증명한다.

6) Session 설정

보통 Client와 Server가 연결되면 Session이 설정된다.

스트림 증명: 클라이언트는 세션이 연결되거나, 메시지 전송전에 인증을 먼저 거쳐야한다.

리소스 바인딩 : 스트림증명후 클라이언트는 스트림에 클라이언트의 주소를 스트림에 바인딩 해야한다. ( user@192.168.0.5/resource)

<session/> 태그에 인증이 됬다는 것을 알리리면 'urn:ietf:params:xml:ns:xmpp-session' 와 같이 보낸다.

<stream:stream

xmlns='jabber:client' // 클라이언트에게

xmlns:stream='http://etherx.jabber.org/streams'

id='c2s_345' // 서버의 누군가의 아이디

from='example.com' // 서버 주소

version='1.0'> // 버전

 

<stream:features> // 즉 이 안에있는게 필요하다

<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>

<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>

</stream:features>

 

Step 1: Client requests session with server: example.com 서버에게 sess_1 유저가 세션 연결 요청을 한다.

<iq to='example.com' type='set' id='sess_1'>

<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>

</iq>

Step 2: Server informs client that session has been created:

// 서버가 sess_1 유저에게 세션이 생성되었다고 알린다.

<iq from='example.com' type='result' id='sess_1'/>

Step 3: 만약 세션연결이 실패하면 실패 메시지를 반드시 보내야한다.

<iq from='example.com' type='error' id='sess_1'>

<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>

<error type='wait'>

<internal-server-error xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> // 서버에러

</error>

</iq>

Step 4 : 만약 아이디나 패스워드가 틀려 인증이 안되어 세션연결이 안 될 경우

<iq from='example.com' type='error' id='sess_1'>

<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>

<error type='auth'>

<forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>

</error>

</iq>

 

// resource 란 패스워드같은 것 을 뜻함.

// 즉 user@192.168.0.5/password

 

* 여기서 알아두어야 할것은 대부분의 메신저 같이 기존에 로긴한 사용자가 있을때 로그인하는경우 기존 로그인 한 쪽이 로그아웃되고, 새로운 유저가 로그인되거나 그 반대가 되게 설정할 수 있다.

- 기존사용자 out, 새로운 사용자 login 일 경우 클라이언트가 받는 메시지

<stream:error>

<conflict xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>

</stream:error>

</stream:stream>

- 기존사용자 유지, 새로운 사용자 out 일 경우 클라이언트가 받는 메시지( 이건 세션 접속 에러 메시지다)

<iq from='example.com' type='error' id='sess_1'>

<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>

<error type='cancel'>

<conflict xmlns='urn:letf:params:xml:ns:xmpp-stanzas'/>

</error>

</iq>

 

7) 메시지 교환

벌써 메세지 교환까지 왔다. 저번까지 분석한것은 어느정도 이해가 된거 같긴하다. 역시 실제로 날려보는게 최고다. 테스트 클라이언트를 만들어서 해보는게 제일 빠를꺼 같다.

메신저의 가장 기본적인 기능 메시지 교환기능 즉 채팅이다.

여기서 중요한게 JID라는건데 이건 아래의 아이디@주소 를 뜻한다. XMPP프로토콜은 이 아이디에 있는 주소를 통해 해당 유저가 어느 서버에 등록되어 있는건지 알아낼수 있는 것이다.

메세지 태그 구문은 다음과 같다.

<message

to='romeo@example.net' // remeo에게

from='juliet@example.com/balcony'

// juliet 로부터 user_id@address/resource (패스워드?)

type='chat' // 유형은 채팅이다.

xml:lang='en'> // 메시지 인코딩 유형

<body>Wherefore art thou, Romeo?</body>

// 메시지 바디.

</message>

 

8) Presence 에 대한 Client와 Server가 꼭 해야하는 일

클라이언트는 세션이 설립되면 초기 presence를 서버에 보내야한다.

서버는 이 클라이언트의 정보를 브로드 캐스팅 해야한다. ( 물론 해당 클라이언트와 연결되어 있는 것들에게) 이때 정보들은 to 태그와 type 태그를 보내야한다.

* 블록킹된 클라이언트에게는 presence 정보를 보내서는 안된다.

처음 정보를 보낸후에는 일정 시간마다 이정보를 서버에 보내 브로드 캐스팅 할것이다.

* Status : 이용상태를 서버에 보내기

<presence>

<show>dnd</show> ==> dtd: busy

</presence>

* 좀 더 세세한 status를 보내기

<presence xml:lang='en'>

<show>dnd</show>

<status>Wooing Juliet</status>

<status xml:lang='cz'>Ja dvo&#x0159;&#x00ED;m Juliet</status>

<priority>1</priority> <== 이건 priority를 주고싶을때

</presence>

* 서버가 romeo 유저의 presence정보를 contact 리스트에게 보낼 때

<presence

type='probe'

from='romeo@example.net/orchard'

to='juliet@example.com'/>

 

<presence

type='probe'

from='romeo@example.net/orchard'

to='benvolio@example.org'/>

 

9) Subscrption

* 다른 클라이언트 유저(다른 엔티티의 프리센스)에게 친구 요청을 할경우

<presence to='juliet@example.com' type='subscribe'/>

* 친구요청 메시지 승낙 ( 메시지를 받은 클라이언트에서 보내는 메시지)

<presence to='romeo@example.net' type='subscribed'/>

* 친구요청 메시지 거부 ( 메시지를 받은 클라이언트에서 보내는 메시지)

<presence to='romeo@example.net' type='unsubscribed'/>

* 친구 삭제 요청 메시지 (클라이언트)

<presence to='juliet@example.com' type='unsubscribe'/>

 

10) Roster 관리(친구관리)

* 서버에 현재 친구리스트를 달라고 요청하기

<iq from='juliet@example.com/balcony' type='get' id='roster_1'>

<query xmlns='jabber:iq:roster'/>

</iq>

 

// 서버로부터 받은 친구 리스트 메시지

<iq to='juliet@example.com/balcony' type='result' id='roster_1'>

<query xmlns='jabber:iq:roster'>

<item jid='romeo@example.net'

name='Romeo'

subscription='both'>

<group>Friends</group>

</item>

<item jid='mercutio@example.org'

name='Mercutio'

subscription='from'>

<group>Friends</group>

</item>

<item jid='benvolio@example.org'

name='Benvolio'

subscription='both'>

<group>Friends</group>

</item>

</query>

</iq>

 

위 코드에서 사용 된 subscription 의 value의 뜻은 다음과 같다.

"none" : 현유저는 상대방의 접속상태모름, 상대방은 나의 접속 상태 모름

"to" : 현유저는 상대방의 접속상태를 암, 상대방은 내정보 모름

"from" : 현유저는 상대방의 정보를 모름, 상대방은 현유저의 접속상태를 암

"both" : 둘다 서로의 접속상태를 알고있음

 

* 친구 추가하기

<iq from='juliet@example.com/balcony' type='set' id='roster_2'>

<query xmlns='jabber:iq:roster'>

<item jid='nurse@example.com'

name='Nurse'>

<group>Servants</group>

</item>

</query>

</iq>

* 이미 존재하는 친구 그룹 등록하기 : 친구추가와 동일한방법이다.

<iq from='juliet@example.com/balcony' type='set' id='roster_2'>

<query xmlns='jabber:iq:roster'>

<item jid='nurse@example.com'

name='Nurse'>

<group>Friends</group>

<group>Lovers</group>

 

</item>

</query>

</iq>

* 서버는 모든 이용가능한 리소스에게 이 수정된 정보를 전송한다.

<iq to='juliet@example.com/balcony'

type='set'

id='a78b4q6ha463'>

<query xmlns='jabber:iq:roster'>

<item jid='nurse@example.com'

name='Nurse'

subscription='none'>

<group>Servants</group>

</item>

</query>

</iq>

 

<iq to='juliet@example.com/chamber'

type='set'

id='a78b4q6ha464'>

<query xmlns='jabber:iq:roster'>

<item jid='nurse@example.com'

name='Nurse'

subscription='none'>

<group>Servants</group>

</item>

</query>

</iq>

 

// 전송이 되면 결과 메시지를 클라이언트에게 전송한다.

<iq to='juliet@example.com/balcony' type='result' id='roster_2'/>

 

* nurse@example.com 이란 친구 삭제하기

<iq from='juliet@example.com/balcony' type='set' id='roster_4'>

<query xmlns='jabber:iq:roster'>

<item jid='nurse@example.com' subscription='remove'/>

</query>

</iq>

 

이상으로 Jabber Protocol을 사용하여 채팅프로그램을 구현하는 방법에 대하여 알아보았다. 각 코드에 대한 내용은 jabber.org 에 나와있는 소스코드를 참고하였다. 마지막으로 다음 절에서는 Jabber의 향후 전망에 대하여 살펴보겠다.

2. 2. 6 Jabber Protocol 향후 전망

- 현재 구글 토크는 서버를 Gmail 사용자에게만 오픈하고 있는데 곧 public server로 등록할 것이라는 내용을 구글 토크 홈페이지에서 간접적으로 언급하고 있다. 그렇게 되면 Jabber는 엄청난 사용자들을 확보 할 수 있을 것이다.(http://www.google.com/talk/about.html#open)

- XMPP(extensible messaging and presence protocol) 메신저는 SIMPLE과 함께 국제 인터넷 표준 기술 협회(IETF)의 인스턴트 메신저 표준 후보 중 하 나로 인텔, 휴렛패커드(HP), AT&T 등이 지원 의사를 밝혔다

 

3. 결론 및 느낀 점

류 명운

당장 앞으로 해야 될 네트워크 기말프로젝트인 채팅프로그램 설계 및 개발에 앞서, 본 과제를 통해 우선, 교수님께서 올려주신 소켓 통신 프로토콜의 분석을 통하여 기본적인 사용 방법을 익혔으며 현재 상용되고 있는 유명한 채팅프로그램에서 사용되고 있는 Jabber프로토콜의 구조 및 작동방식에 대한 전반적인 조사를 통하여 전에 없었던 프로토콜 설계에 관한 지식이 어느정도 자리잡게 되었습니다.



반응형