키스맥 - 리얼베이직 매킨토시 전문 웹 매거진 웹진

  + 파일메이커 기초편
  + 4th Dimension
  + 리얼베이직
  + OS X 10.3
  + 홈페이지 만들기
  + 포토샵 강좌
  + 디카 완전정복
  + 실무로 배우는 Quark
  + MLayout
  + iPod 강좌
  + html 강좌
  + 간단매뉴얼&팁
  + 5세대 iPod 강좌
  + iTunes 한 컷 강좌
  + iPod 한컷강좌
            


16회. 리얼베이직의 기초 -14- 네트웍


지난 강좌에서는 퀵타임에 대해서 공부해봤습니다. 퀵타임의 뛰어난 멀티미디어 기능과 리얼베이직에서 사용에 대해서 공부했었습니다. 이번에는 네트웍에 대해서 공부해보도록 하겠습니다. Mac OS X 의 네트웍에 대한 내용과 리얼베이직에서 네트웍 프로그래밍의 기반인 소켓에 대해서 공부를 해보도록 하겠습니다. 그럼 시작해볼까요?


Mac OS X는 이전의 Mac OS 9 에 비해서 많은 안정적인 환경을 제공하고 있습니다. 꾸준한 버젼업으로 현재 10.3 버젼은 굉장히 안정적인 환경을 제공하고 있지요. Mac OS 9 에 비해서 훨씬 안정적으로 개선된 부분 중 하나가 바로 네트웍 부분입니다. Mac OS 9 에서는 네트웍이 죽게 되면 시스템 전체에 영향을 끼쳐서 네트웍 부분 자체가 다운이 되는 경우가 많았습니다. 하지만 Mac OS X 에서는 그러한 문제점들이 완벽하게 개선이 되어 굉장히 안정적이고 빠른 네트웍 환경을 경험할 수 있습니다.

Mac OS X 의 네트웍 기반을 이루고 있는 프로토콜은 당연히 TCP/IP(Transmission Control Protocol/Internet Protocol) 입니다. TCP/IP 는 다른 시스템에도 사용되는 네트웍 표준 프로토콜이라 보시면 됩니다. 그럼 TCP/IP의 사전적인 의미에 대해서 알아보도록 하겠습니다.

[기종이 서로 다른 컴퓨터 시스템을 서로 연결해 데이터를 전송하기 위한 통신 프로토콜으로서 1980년 초 미국 국방부가 제정하였다. 유닉스(UNIX) 운영체제 내에 채용되었으며 인터넷에도 사용되었고, 유닉스와 인터넷 사용이 늘어나면서 TCP-IP는 네트워크상에서 데이터를 전송하는 표준이 되었다.

미국 국방부에서 구축한 전산망인 알파넷(ARANET)에서 개발된 프로토콜으로서 1983년 1월 알파넷에서 NCP 대신에 이 표준을 사용하였다. 그 후에 알파넷에서 Milnet를 독립시키고, 이 두 네트워크 사이의 통신으로 인터넷을 이용할 무렵 미국 방위통신청(DCA;Defense Communication Agency)이 모든 알파넷을 이용하는 호스트 컴퓨터를 TCP-IP로 사용하도록 한 것이 시초가 되었다.

TCP-IP의 기본 서비스에는 원격 로그인, 파일전송 및 전자우편이 있다. 이 밖에도 TCP-IP에 의해 연결된 네트워크 장치는 LAN 노드(node)의 물리적인 주소를 살핀다든지, 기기의 영문자를 숫자명으로 매핑한다든지, 네트워크를 관리한다든지 하는 등의 작업을 할 수 있다. 독립적인 개방형 구조로서 이들 일련의 프로토콜은 호스트의 하드웨어 ·운영체제 ·접속매체의 차이와 관계없이 동작되도록 설계되어 있다.

TCP/IP[티씨피 아이피]는 인터넷의 기본적인 통신 프로토콜로서, 인트라넷이나 엑스트라넷과 같은 사설 망에서도 사용된다. 사용자가 인터넷에 접속하기 위해 자신의 컴퓨터를 설정할때 TCP/IP 프로그램이 설치되며, 이를 통하여 역시 같은 TCP/IP 프로토콜을 쓰고 있는 다른 컴퓨터 사용자와 메시지를 주고받거나, 또는 정보를 얻을 수 있게된다.

TCP/IP는 2개의 계층으로 이루어진 프로그램이다. 상위계층인 TCP는 메시지나 파일들을 좀더 작은 패킷으로 나누어 인터넷을 통해 전송하는 일과, 수신된 패킷들을 원래의 메시지로 재조립하는 일을 담당한다. 하위계층, 즉 IP는 각 패킷의 주소부분을 처리함으로써, 패킷들이 목적지에 정확하게 도달할 수 있게 한다. 네트웍 상의 각 게이트웨이는 메시지를 어느 곳으로 전달해야할지를 알기 위해, 메시지의 주소를 확인한다. 한 메시지가 여러 개의 패킷으로 나뉘어진 경우 각 패킷들은 서로 다른 경로를 통해 전달될 수 있으며, 그것들은 최종 목적지에서 재조립된다.

TCP/IP는 통신하는데 있어 클라이언트/서버 모델을 사용하는데, 컴퓨터 사용자(클라이언트)의 요구에 대응하여, 네트웍 상의 다른 컴퓨터(서버)가 웹 페이지를 보내는 식의 서비스를 제공한다. TCP/IP는 본래 점대점(点對点) 통신을 하는데, 이는 각 통신이 네트웍 상의 한점(또는 호스트 컴퓨터)으로부터 시작되어, 다른 점 또는 호스트 컴퓨터로 전달된다는 것을 의미한다. TCP/IP와 TCP/IP를 이용하는 상위계층의 응용프로그램들은 모두 "커넥션리스 (connectionless)"라고 불리는데, 이는 각 클라이언트의 요구가 이전에 했던 어떠한 요구와도 무관한 새로운 요구로 간주된다는 것을 의미한다 (일상적인 전화통화가 통화시간 내내 지속적으로 연결되어 있어야 하는 것과는 다르다). 커넥션리스는 네트웍을 독점하지 않으므로, 모든 사람들이 그 경로를 끊임없이 공동으로 사용할 수 있게 한다 (사실 TCP 계층 그 자체는 어떤 한 메시지가 관계되어 있는 한 커넥션리스가 아니라는데 유의해야 한다. TCP 접속은 어떤 한 메시지에 속하는 모든 패킷들이 수신될 때까지 계속 유지된다).

많은 인터넷 사용자들이 TCP/IP를 이용하는 상위계층 응용프로토콜에 대해서는 잘 알고 있다. 이러한 상위계층 프로토콜에는 웹서비스에 사용되는 HTTP를 비롯하여, 멀리 떨어져 있는 원격지의 컴퓨터에 로그온할 수 있게 해주는 Telnet (Telnet), 그리고 파일전송에 사용되는 FTP (File Transfer Protocol)와 메일 전송에 사용되는 SMTP (Simple Mail Transfer Protocol) 등이 있다. 이러한 프로토콜들은 종종 TCP/IP와 함께 패키지로 일괄 판매된다.

PC 사용자들은 보통 인터넷에 접속하기 위해 SLIP (Serial Line Internet Protocol)이나 PPP (Point-to-Point Protocol) 프로토콜을 사용한다. 이러한 프로토콜들은 다이얼업 전화접속을 통해 접속서비스사업자의 모뎀으로 보내질 수 있도록 IP 패킷들을 캡슐화한다.

TCP/IP와 관련이 있는 프로토콜로 UDP (User Datagram Protocol)가 있는데, 이것은 특별한 목적을 위해 TCP 대신에 사용되는 것이다. 라우팅 정보를 교환하기 위해 네트웍 호스트 컴퓨터에 의해 사용되는 프로토콜에는 ICMP (Internet Control Message Protocol), IGP (Interior Gateway Protocol), EGP (Exterior Gateway Protocol), 그리고 BGP (Border Gateway Protocol) 등이 있다.] *인터넷 지식 검색 참조.

위의 내용처럼 TCP/IP 유닉스에서 부터 사용되어온 네트웍 프로토콜의 표준 규약이라고 생각을 하시면 됩니다.

네트웍 환경이라 함은 우리가 일반적으로 사용하는 웹과 같은 인터넷 환경이나, FTP, Telnet, 메신저 등의 모든 인터넷 환경을 말합니다. 위의 네트웍 서비스 들이 모두 TCP/IP 에 기반을 하고 있지요. 모두 같은 환경을 사용하지만 각각은 포트라는 경로를 구분하여 사용이 되고 있습니다. TCP/IP 에는 위의 해당 서비스 마다 별도의 포트를 갖고 있습니다. 예를 들어서 웹 서비스는 80번을 사용하고 FTP 는 21번, Telnet 은 23번을 사용하죠. 메일을 보내는 SMTP 서버는 25 번 포트를 사용하지만 메일을 받는 POP3 프로토콜은 110번을 사용합니다. 포트는 1023 이하의 모든 번호는 정해진 서비스에만 사용되기 때문에 어떤 포트를 사용하느냐에 따라서 어떤 서비스를 사용한다라고 알 수 있습니다. 임의적으로 네트웍 프로그램을 만들려면 이 포트를 정해줘야 하는데 1023 이하의 포트 번호는 앞서 언급한 서비스 외에 시스템에서 미리 사용하고 있습니다. 따라서 미리정해진 서비스가 아닌 임의의 네트웍 프로그램을 만들려면 1024 숫자 이상의 포트 번호를 이용해야 합니다.

하지만 주의할점은 1024이상에서도 미리 약속이 된 것처럼 사용되는 포트들이 있다는 것입니다. MySQL 과 같은 데이타베이스는 TCP/IP 네트웍 서비스를 이용할 시에 기본 포트로 3360을 사용합니다. 메신저나 IRC 등도 1024 이상의 포트를 사용하기 때문에 이러한 유명 프로그램들이 사용하는 포트는 사용하지 않는 것이 좋습니다. 인터넷에서 네트웍 관련 프로그램들의 RFC 문서를 찾아서 참조하면 미리 사용되고 있는 포트들에 대해서 잘 알 수 있을 것입니다.

Mac OS X 에는 이러한 안정적인 네트웍 프로토콜을 기반으로 하여 애플쉐어, Samba, 아파치를 이용한 웹서비스, FTP, Telnet 등의 서비스를 기본으로 내장하여 서비스 하고 있습니다.

이러한 안정적인 네트웍 환경은 리얼베이직에서 소켓을 이용한 네트웍 프로그램을 만드는데 큰 도움을 줍니다. Mac OS 9 대에서는 네트웍 프로그램을 만들다가 버그가 있거나 다운이 되면 시스템을 재시동해야하는 경우가 빈번했기 때문이죠. 따라서 Mac OS X 는 리얼베이직을 이용하여 네트웍 프로그램을 만들기에 더 없이 좋은 환경이라 할 수 있습니다. 그럼 리얼베이직의 네트웍 프로그램에 대해서 알아보도록 하겠습니다.


리얼베이직에서 네트웍에 관련된 프로그램은 모두 Socket 콘트롤을 기반으로 이루어 집니다. 이 Socket 콘트롤은 TCP/IP 를 기반으로 하고 있기 때문에 웹, FTP, Telnet 등 모든 TCP/IP 기반 서비스를 이용하고 프로그램을 만들 수 있습니다. 현재 강좌를 진행하기 위해 기본으로 삼고 있는 5.2.4 이전 버젼에서는 Socket 콘트롤은 한가지였습니다. 한가지 Socket 콘트롤만을 이용하여 웹이나 FTP 기타 여러가지 네트웍 관련 소프트웨어를 만들 수 있었습니다. 사용이 간단하였고 기능도 쓸만해서 굉장히 자주 사용했었던 콘트롤 중에 하나였죠. 예전에 iTalk 이라는 메신저 프로그램이 이 소켓을 기반으로 하여 서버와 클라이언트 모두 개발을 했었습니다.

하지만 5.2.4 버젼에 이르러서는 이 Socket 콘트롤이 좀 더 세분화 되었습니다. HTTP 를 위한 HTTPSocket 클래스와 서버 기능을 위한 ServerSocket 클래스, 이메일 전송을 위한 SMTPSocket 클래스, 보안 접속을 위한 SSLSocket 클래스등으로 나뉘었습니다. 또한 보다 간편하게 사용하기 위한 TCPSocket, UDPSocket 클래스도 생겼습니다. 또한 Email 서비스를 제대로 지원하기 위해서 EmailAttatchment 클래스, EmailHeader 클래스, EmailMessage 클래스, POP3Socket 클래스 등도 포함이 되었습니다. 아직 공부하지는 않았지만 5.5x 버젼에서는 최근 인터넷 서비스를 위해서 SOAP 이나 XML 을 위한 클래스도 추가가되었습니다.

*5.5 버젼에 대해서는 나중에 5.2.4 버젼과 비교해서 어떤것이 바뀌고 더 좋아졌는지에 대해서 알아보고 새로운 기능에 대해서 알아보도록 하겠습니다.

리얼베이직은 초창기부터 지금까지 네트웍에 관련된 내용들을 꾸준히 추가해왔고 5.5 버젼에 이르러서는 충분하지는 않아도 많은 가능성을 볼 수 있는 네트웍 및 인터넷에 관련된 기능들을 추가해왔습니다. 5.52에서는 콘솔 어플리케이션 및 Linux 까지도 지원을 하여 서버 프로그래밍에 관한 가능성도 보여주고 있습니다. 실질적으로 가능성 뿐 아니라 실질적으로 응용해서 리눅스나 Mac OS X 에서 서버용 프로그램을 만들어서 사용하는 개발자들이 많으며 대표적으로 iTalk 메신저의 서버도 리얼베이직으로 만들어졌습니다.

만약에 이 글을 읽는 여러분들이 네트웍 프로그래밍에 관심이 많고 리얼베이직에도 관심이 많다면 리얼베이직을 이용해서 네트웍 프로그램을 만들어 보라고 권하고 싶습니다. 그만큼 충분한 기능과 효과를 거둘 수 있으리라 생각합니다.


그럼 리얼베이직의 네트웍 프로그래밍의 기본을 이루고 있는 Socket 은 SocketCore 클래스 입니다. 이 클래스를 기반으로 다양한 콘트롤이나 클래스가 존재합니다. 예를 들어서 기본적인 네트웍 기능을 구현하는 TCPSocket 콘트롤이나 웹 접속을 하여 웹의 정보를 가져올 수 있는 HTTPSocket Class와 HTTPSecureSocket Class, 이메일 정보를 가져올 수 있는 POP3Socket Class와 POP3SecureSocket Class, 메일을 보내는 기능을 갖고 있는 SMTPSocket Class 와 SMTPSecureSocket Class, 인터넷 스트리밍 방송에서 사용되는 UDPSocket Class, 보안 접속이 가능한 SSLSocket Class, 서버 기능을 대체해주는 ServerSocket Class 등이 있습니다. 또한 소켓은 아니지만 POP3 나 SMTP Socket 과 같이 사용하여 쉽게 이메일을 관리할 수 있는 EmailAttatchment, EmailHeaders, EmailMessage Class 등이 있습니다. 이러한 클래스들은 예전에 Socket 클래스 한가지로 모두 구현하던 것을 기능에 따라 여러가지 부분으로 나눈 것으로써 리얼베이직에서 더욱 더 쉽게 네트웍 프로그래밍을 할 수 있도록 해주는 클래스들입니다. 그럼 이러한 Socket 클래스에 대해서 자세히 알아보도록 하겠습니다.


리얼베이직에서는 예전에는 네트웍에 관련해서는 Socket 콘트롤만이 존재했었습니다. 하지만 이제 Socket 콘트롤은 TCPSocket 콘트롤이나 다른 Socket 클래스의 기반을 이루는 Socket 클래스로 대체되어서 상위클래스에서는 SocketCore 클래스가 존재하고 Socket 콘트롤은 이제 사용되지 않습니다.
하지만 TCPSocket 이라는 이름으로 전과 동일하게 사용됩니다. 그럼 새롭게는 아니지만 이름이 바뀐 TCPSocket 클래스의 기본적인 속성과 함수에 대해서 알아보도록 하죠.

*다음의 내용은 온라인 도움말에 나와있는 TCPSocket 에는 없는 부분도 있습니다. 하지만 실질적으로 사용할 때에는 모두 사용이 가능하고 나타나는 부분이지요. 왜냐하면 TCPSocket 은 SocketCore 의 모든 속성과 함수, 이벤트들을 포함하고 있기 때문입니다. 따라서 SocketCore 부분과 TCPSocket 의 속성을 포함하고 내용을 정리 했습니다.

- 속성(Properties)
* Address : 접속하거나 데이타를 보낼 상대방의 네트웍 주소를 말합니다. 이 속성이 없다고 하면 접속 자체를 할 수 없으니 데이타를 보낼 수도 없겠죠. 반드시 접속시에 필요하다고 생각하시면 됩니다. 네트웍 주소는 숫자나 도메인 명이 가능합니다. 도메인명이 없을 경우는 "192.168.1.1" 식의 주소값을 갖게 되고 도메인이 별도로 있을 경우는 "michelin.zdns.net" 이런식으로 갖게 되겠죠. 따라서 데이타 타입은 문자형인 String 입니다.
* BytesAvailable : 데이타를 받을 때 사용되는 내부 버퍼 사이즈를 정해줍니다. 이 속성은 5.x 대에 와서 새로 생긴 속성입니다. 이전에는 이러한 속성이 없어서 임의적으로 Bytes 크기를 계산해서 데이타를 전송해야 했습니다. 소켓이 한번에 받는 데이타 사이즈는 4096 정도인 4K 정도였는데 지금은 정확히 테스트 해본 내용은 없지만 이러한 별도의 속성이 존재를 하니 이제는 이 속성에 기반해서 데이타를 받아들일 수 있을 것입니다. BytesAvailable 속성의 데이타 타입은 크기를 나타내기 때문에 정수형인 Integer 형입니다.
* IsConnected : 현재 Socket 이 네트웍에 접속이 되어있는지 아닌지를 나타내 줍니다. IsConnected 속성은 Mac OS X 시스템이 네트웍에 접속된 상태를 나타내는 것이 아니라 리얼베이직으로 만들어진 프로그램이 특정 서버에 접속이 되어있는지를 나타내는 속성입니다. 따라서 프로그램을 만들 때 이 속성을 자주 체크하게 해주면 네트웍이 불안한 곳에서는 현재 네트웍 접속이 끊어졌는지 계속 연결중인지를 손쉽게 확인할 수 있습니다. 최근 국내의 인터넷 환경은 인터넷 속도도 빠르고 굉장히 안정적이지만 과거 초창기 때의 케이블이나 ADSL 들은 하루에도 수십번은 접속이 끊어지는 현상이 많이 생길정도로 불안하였습니다. 항상 네트웍 접속 상태를 확인 할 때에는 IsConnected 속성을 사용하시기 바랍니다. IsConnected 속성의 데이타 타입은 참과 거짓을 나타내는 Boolean 형입니다.
* LastErrorCode : 네트웍 연결이나 데이타 전송시 에러가 발생 했을 경우에 발생되었던 맨 마지막 에러코드를 나타냅니다. Socket 클래스의 이벤트에서 에러가 발생할 때 발생되는 이벤트로 Error 이벤트가 있습니다. 이 Error 이벤트가 발생한 뒤에 LastErrorCode 에 마지막 코드가 등록이 되게 됩니다. Error 코드에 따른 내용은 별도의 온라인 도움말을 보시면 확인이 가능하여 에러의 내용은 다음과 같습니다.
- 100
네트웍 드라이버를 초기화 하거나 오픈하는데 에러 발생합니다.
- 102
연결이 끊김
- 103
주소를 찾을 수가 없음을 나타내는 에러입니다. 잘못된 주소를 넣거나 전혀 존재하지 않는 주소를 사용하게 되면 이 에러가 발생합니다.
- 105
이 에러는 현재 주소나 포트가 사용되고 있을 때 발생합니다. 예를 들어서 뒤에나올 Listen 함수를 통해서 하나의 Port를 점유하고 있는데 똑같은 Port를 이용해서 다시 Listen 함수를 사용하면 이 에러가 발생하게 됩니다.
- 106
잘못된 방식으로 Socket 을 사용하려고 할 때 발행하는 에러. 예를 들어서 UDPSocket 을 사용하는 Multicast 그룹에 접근하기 전에TCPSocket 으로 데이타를 보내려고 하는 경우가 이에 해당. 하지만 그다지 많이 발생하는 에러는 아님. 에러가 발생한다면 Socket 의 종류나 접근 방식을 한번 점검해 보는 것이 좋음.
- 107
이 에러는 할당된 Port 가 적절하지 못해서 유효하지 않다라는 것을 알려주는 에러코드입니다. Port 는 1~1023 까지는 시스템에서 미리 정해놓고 사용하도록 되어있는데 이 내부의 Port 를 지정하고 Listen 같은 함수를 사용하여 107 에러가 발생하게 되어있습니다. 따라서 1024~65535까지의 범위에 있는 Port 번호를 이용해야 합니다. 당연히 다른 프로그램에서 미리 점유하고 있는 포트는 피해야겠죠?
- 101, 104
이 에러코드는 현재 5.x 버젼에서는 사용되지 않는 에러이며 나타나지도 않습니다. 혹시 이전의 4.x 버젼대를 사용하면 나타날 수도 있겠군요.
마지막 에러 내용을 자주 확인하기 위해서는 온라인 도움말을 참조하시기 바랍니다. LastErrorCode 속성의 데이타 타입은 숫자 코드를 나타내는 Integer 형입니다.

* LocalAddress : 현재 자신의 매킨토시에 할당되어있는 IP 주소를 나타냅니다. 가상 아이피로 할당되었을 경우는 가상 아이피가 나타나게 됩니다. LocalAddress 속성의 데이타 타입은 문자를 나타내는 String 형입니다.
* Port : 접속을 하고 데이타를 주고 받기 위해 사용되는 포트를 나타냅니다. 앞서 언급한 것 처럼 FTP는 21번, Telnet 은 23번, HTTP 는 80 등을 사용합니다. Port 속성의 데이타 타입은 숫자를 나타내는 Integer 형입니다.
* PPPStatus : 모뎀을 이용한 전화선 연결시에 사용되는 PPP 프로토콜의 상태를 나타냅니다. 하지만 이 속성은 System Object의 PPPStatus 에 의해서 대치되어 사용됩니다. 따라서 실질적으로 Socket 클래스의 PPPStatus 는 사용되지 않습니다. PPPStatus 속성의 데이타 타입은 숫자를 나타내는 Integer 형입니다.
* RemoteAddress : Socket 에 접속된 상대방 컴퓨터(서버)의 주소를 나타냅니다. Domain 명을 이용하여 접속을 했다 하더라도 이 속성을 이용하면 실질적인 IP 주소를 확인할 수 있습니다. RemoteAddress 속성의 데이타 타입 역시 주소를 나타내기 때문에 문자를 나타내는 String 형입니다.

- 이벤트(Events)
TCPSocket 콘트롤의 이벤트에는 다음과 같은 5가지 이벤트가 있습니다. 이에 대해서 자세히 알아보도록 하죠.

* Connected : Socket 이 접속 될 때 발생되는 이벤트 입니다. Socket 의 접속은 Connect 함수를 통해서 이루어지고 올바른 주소(Address 속성)와 Port 속성이 할당되어야 에러없이 접속이 이루어 집니다. 에러 없이 접속이 이루어 지면 Connected 이벤트가 발생이 되며 이 이벤트 내부에 작성된 코드가 실행이 되게 됩니다. 따라서 접속시에 프로그램에서 접속을 알리거나 특정 동작을 하게 하려면 Connected 이벤트 내에 코드를 작성하면 됩니다.
* DataAvailable : Socket 의 버퍼내에 새로운 데이타가 들어올 수 있게 되면 발생이 되는 이벤트 입니다. 데이타가 들어올 때마다 특정 코드를 수행하도록 하려면 이 벤트에 코드를 작성하면 됩니다.
* Error : 에러가 발생하면 발행하는 이벤트 입니다. 특정 에러가 발생했을 경우 이 이벤트 내에 LastErrorCode 속성을 확인해 보면 어떤 에러가 발생했는지를 알 수 있습니다.
* SendComplete : Socket 을 통해서 데이타가 모두 전송 될 때 발생하는 이벤트 입니다. 이 이벤트는 UserAborted 라는 Boolean 형의 속성을 인수로사용합니다. 이 값이 False 이면 데이타가 제대로 전송이 된 것을 나타내고 True 를 리턴하게 되면 중간에 데이타가 전송중에 취소 된 것을 나타냅니다. 데이타가 전송중 취소되는 것은 SendProgress 이벤트에서 Return 값으로 True 를 리턴하게 되면 데이타 전송이 취소 된것으로 나타납니다.
* SendProgress : 데이타가 전송중에 발생되는 이벤트 입니다. 이곳에서는 BytesSent 와 BytesLeft 라는 인수를 받게 됩니다. 이 인수 값을 통해서 얼마나 많은 데이타가 전송되는지를 확인할 수 있습니다. 이 이벤트는 리턴값을 갖는데 이 값이 False 면 제대로 전송이 끝나는 것을 나타내고 중간에 True 값을 리턴하게 되면 전송이 취소된것을 나타냅니다. 이 이벤트에서 True 를 리턴하여 전송을 취소하게 되면 SendComplete 의 UserAborted 속성에서 True 값을 받고 전송이 취소됨을 나타내게 됩니다.

- 함수( Methods)
* Close : 접속된 Socket 의 연결을 닫아 줍니다.
* Connect : Socket 클래스의 Address 속성과 Port 속성을 이용하여 Socket을 연결해 줍니다. 접속이 제대로 이루어 지면 IsConnedted 속성은 True 로 설정이 되고 Connect 이벤트가 발생되게 됩니다. 그렇지 않으면 Error 이벤트가 발생하면서 LastErrorCode 속성을 통해 어떤 이유로 접속이 실패했는지 확인 할 수 있습니다.
* Disconnect : 연결된 접속을 끊어 줍니다. 또한 102 에러를 발생시켜서 현재 Socket 접속이 끊어졌다라고 알려주게 됩니다.
* Listen : 이 함수는 해당 소켓을 다른 소켓과의 연결을 위해서 기다리는 모드로 만들어 줍니다. 즉 서버로 사용될 때 사용하는 함수 입니다. 다른 컴퓨터에 접속을 하려고 하면 Connect 함수를 사용하여 접속을 하겠지만 다른 컴퓨터가 자신의 컴퓨터에 접속하게 하려면 Listen 함수를 실행하고 기다리게 됩니다. 물론 Listen 시에는 접속할 서버 주소인 Address 속성은 설정하지 않아도 되지만 Port 는 설정되어있어야 합니다. 이 함수는 서버 프로그램을 만들때에는 필수인 함수입니다.
* LookAhead : 현재 버퍼에서 삭제되지 않고 남아있는 캐릭터 내용을 보여줍니다.
* Poll : 해당 Socket 콘트롤의 속성들을 새롭게 업데이트 해주고 어떤 새로운 데이타가 들어오게 되면 DataAvailable 이벤트가 발생하도록 합니다.
* PPPConnect : 모뎀을 이용한 전화연결시 사용이 되는 함수입니다. 이는 System Object 의 같은 함수인 PPPConnect에 의해서 대체됐기 때문에 사용되지는 않습니다.
* PPPDisconnect : 모뎀을 이용한 PPP 연결을 끊어 줍니다. 이는 System Object 의 같은 함수인 PPPDisconnect에 의해서 대체됐기 때문에 사용되지는 않습니다.
* Purge : Socket 의 받은 데이타 버퍼를 추기화 해줍니다. 보내는 데이타 버퍼에는 영향을 끼치지 않습니다.
* Read : 이 함수는 Socket 을 통해 들어오는 데이타들을 읽어주는 역할을 합니다. Byte 단위로 데이타를 읽을 수 있으며 한번에 얼마만큼의 데이타를 읽어들일지 결정해주는 Integer 형의 Count 값을 인수로 사용합니다. 원하는 만큼의 데이타를 바이트 단위로 읽어들이기 위해서는 이 함수를 사용하면 됩니다.
* ReadAll : Socket 콘트롤의 버퍼에 있는 모든 내용을 읽어 들입니다. 해당 버퍼의 내용을 모두 읽고 그 내용을 문자형 데이타로 리턴해 줍니다.
* Write : 데이타를 소켓을 통해 보낼 때 사용됩니다. 보내지는 데이타는 String 형의 데이타를 보내게 됩니다. 이미지나 바이너리 데이타들은 Base64 함수를 통해서 텍스트 문자로 변경후에 보내야 에러가 발생하지 않고 제대로 보내지게 됩니다.


HTTPSocket 클래스는 이름에서 알 수 있듯이 웹을 위한 클래스 입니다. Get 이나 Post 를 지원해주기도 하고 파일을 첨부하여 손쉽게 HTTP 를 통해 파일을 전송하거나 받을 수 있게 해줍니다. 하지만 아쉬운 것은 HTML 을 읽어서 웹과 같이 표현해주는 기능은 없고 단순히 데이타를 주고 받은 송수신 기능만이 있다는 점입니다.

* 리얼베이직에서 HTML의 랜더링은 MBS 플러그인을 이용하여 Webkit 이나 HTML 랜더링 엔진을 이용하면 됩니다. HTML 랜더링 엔진을 이용할 시에는 HTTPSocket 을 이용하여 데이타를 받은 후에 랜더링을 하면 됩니다. MBS 플러그인에 대해서는 차후에 따로 공부해 볼 것입니다.

이렇게 랜더링 앤진이 바져있음에도 HTTPScoket 은 몇가지 편리함을 제공해 줍니다. 별도의 Connect 함수가 없음에도 Get 함수등과 같이 몇가지 함수를 이용하면 자동으로 접속을 해주고 해당 페이지의 HTML 소스를 가져옵니다. 또한 별도의 포트 또한 지정을 하지 않습니다. 왜냐하면 HTTPSocket 은 기본적으로 80번 포트를 사용하기 때문이지요.

그럼 HTTPSocket 에 대해서도 속성과 이벤트, 함수에 대해서 자세히 알아보도록 하겠습니다. HTTPSocket 은 별다른 속성은 없으며 SocketCore 클래스와 TCPSocket 콘트롤이 갖고 있는 모든 속성을 갖고 있습니다. 따라서 HTTPSocket 클래스의 속성에 대해서는 정리하지 않도록 하겠습니다.
*리얼베이직 5.5x 버젼에서는 HTTPSocket 에 HTTPProxyAddress 와 HTTPProxyPort 라는 속성이 추가되었습니다.

- 함수(Methods)
* ClearRequestHeaders : 정의된 request header 를 모두 초기화 합니다. 자세한 내용은 SetRequestHeader 의 설명을 참조하시기 바랍니다.
* EncodeFormData : 이 함수는 Dictionary 타입의 Form 데이타를 인수로 사용합니다. 여러분들도 알다시피 Dictionary 타입은 인덱스 값을 이용하여 하나의 Disctionary 타입의 변수에 다양한 타입의 데이타를 입력할 수 있는 Variant 타입과 비슷한 데이타 유형입니다. 오히려 Dictionary 타입 자체가 여러개의 데이타 타입을 모아서 만든 구성체라고도 할 수 있겠습니다. 이 곳에 PHP 의 Get 이나 Post 에서 사용할 수 있는 Form Data를 입력하고 이 내용을 EncodeFormData 함수를 이용해서 변환을 시키면 HTTPSocket 의 Get 이나 Post 함수에서 사용할 수 있는 데이타로 변환이 되게 됩니다. 이 함수는 String 타입의 값을 리턴하는데 이 내용이 바로 Get 이나 Post 함수에서 이용이 되는 것 입니다. PHP 에 대해서 잘 알고 계신분들은 이를 이용하는데 편리하게 응용하여 사용할 수 있으리라 생각됩니다.
*Dictionary 데이타 타입에 대해서는 앞서 배웠던 데이타 유형을 참조하시거나 온라인 도움말의 Dictionary 를 참조하시기 바랍니다.
* Get : 지정된 URL 로부터 받는 데이타를 가져옵니다. Get 함수는 String 타입의 URL 주소를 인수로 사용합니다. 이 URL 주소에 접속해서 받는 HTML 내용을 모두 가져오게 되는 것이죠. 별도의 옵션 인수로는 FolderItem 타입의 File 이라는 인수를 사용합니다. 이 인수를 지정하게 되면 Get 함수를 통해서 받아지는 HTML 내용들을 모두 지정된 File 인수에 저장을 해줍니다. Get 함수가 실행되면 PageReceived 이벤트가 발생이 되고 이곳에서 데이타가 받아들여지게 됩니다. Get 함수를 통해서 데이타가 모두 받아지게 되면 자동적으로 DownloadComplete 이벤트가 발생하기 때문에 데이타 완료를 알 수 있습니다. Get 함수에 대해서는 뒤에 간단하게 예제 통해서 확인해 보도록 하겠습니다.
* Post : 폼 데이타를 입력할 때 사용되는 Post 명령어를 웹서버에 전송합니다. 이때에는 Get 함수 처럼 PageReceived 이벤트가 발생이 되고 이곳에서 데이타가 받아들여지게 됩니다. 역시 Get 함수처럼 URL 주소가 인수로 사용되며 받는 데이타를 저장할 수 있는 FolderItem 형식의 File 도 인수로 사용을 합니다. 그리고 데이타가 모두 받아지게 되면 Get 함수처럼 DownloadComplete 이벤트가 발생하여 데이타 송수신 완료를 알 수 있습니다.
* SetFormData : Post 를 통해서 웹서버에 데이타를 보낼 경우 주어진 내용을 이용하여 Post 폼을 만들어 줍니다. 이를 위해서 SetFormData 함수는 Dictionary 타입의 Form 값을 인수로 사용합니다. 이 Form 에는 Post 시에 사용될 변수명(?)과 그 값이 들어가게 됩니다. 예를 들면 다음과 같을 수 있겠죠.
form.value("mail") = "kissmac@kissmac.com"
form.value("name") = "kissmac"
form.value("status") = "using"
위의 Form 데이타를 이용해서 SetFormData 함수를 사용하면 Post 할 수 있는 데이타가 설정되게 됩니다.

* SetPostContent : Post 되어서 서버에 전송될 내용과 타입을 지정해 줍니다.
* SetRequestHeader : Header 값을 지정합니다. 일반적으로 사용되는 Header 에는 OS 타입이나, CPU, 참조 페이지, Client Name 등이 해당됩니다.

- 이벤트(Events)
* Connected : Web 서버와 접속이 이루어 지면 발생하는 이벤트 입니다. HTTPSocket 은 별도의 Connect 함수는 사용하지 않고 자동적으로 접속을 실행한다고 하였습니다. 그리고 데이타를 다 받게 되면 접속도 자동적으로 끊기게 됩니다.
* DownloadComplete : Get 이나 Post 함수가 사용된 후에 다운로드가 완료되면 발생하는 이벤트 입니다. 이 이벤트에서는 4가지의 인수를 받기 때문에 이를 통해서 여러가지 상태를 알 수 있습니다. URL, HTTPStatus, Headers, File 의 4가지 인수를 받아들이며 이는 코드에디터를 통해서도 바로 확인할 수 있습니다. URL은 다운로드 받는 URL의 주소를 나타내며, HTTPStatus 는 각 해당되는 동작에 따라서 여러가지 인수 값을 정수형으로 받아들입니다. 예를 들어서 Error 번호가 404번이면 이는 "Page not found" 를 나타냅니다. headers 는 서버에서 전송되는 HTTP Header 값을 Dictionary 타입으로 받아들입니다.
* Error : 이 이벤트는 이름 그대로 에러가 생기면 발생하는 이벤트 입니다. TCPSocket 의 에러코드와 거의 동일하지만 추가된 코드가 하나 있습니다. 1번 에러인데 이는 다운로드 된 파일이 생성되지 않으면 발생하는 에러입니다. Error 이벤트는 이렇게 발생되는 정수형의 에러코드를 인수로 받아들이기 때문에 이 에러를 체크함으로서 언제든지 발생하는 에러에 대해서 어떤 에러인지를 확인하고 조치할 수 있습니다.
* HeadersReceive : 서버에서 header 의 내용이 전송되면 발생하는 이벤트 입니다. Header 라는 Dictionary 타입의 객체를 인수로 사용합니다.
* PageReceive : 이 함수는 HTTPSocket 이 실질적이 페이지 정보를 다운로드 하게 되면 발생하는 이벤트 입니다. 이 이벤트도 URL, HTTPStatus, Headers, Content 라는 인수를 사용하며 String 타입의 Content 인수 값을 통해서 실질적인 Page HTML 코드를 가져오게 됩니다. 물론 PHP 나 다른 CGI 의 소스를 가져오는 것이 아니라 그 결과값을 가져오게 되겠죠.
* ReceiveProgress : URL 을 통해서 데이타를 가져올 때마다 발생하는 이벤트 입니다. 정수형타입의 BytesReceived 인수와 정수형타입의 TotalBytes 인수를 받아들임으로써 현재 진행되고 있는 데이타의 크기를 알 수 있습니다.
* SendProgress : 이 이벤트는 HTTPSocket 클래스를 통해서 데이타가 전송이 될 때 발생하는 이벤트 입니다. 정수형의 Bytes 인수를 이용하여 현재 전송되고 있는 데이타의 Bytes 수를 알 수 있습니다.
리얼베이직의 HTTPSocket 클래스는 사용하기 굉장히 쉽고 HTTP 의 기본 기능을 충실히 지원하지만 뭔가 빠진듯한 아쉬운 클래스입니다. HTTP 를 랜더링해주는 별도의 기능이 아쉽다라고 할 수 있습니다. 하지만 기존에 구축되어있는 웹서비스와 연동하여 부분적인 서비스를 이용할 경우는 HTTP 프로토콜을 이용하여 훌륭한 프로그램을 만들 수 있는 기반이 됩니다.


POP3Socket 클래스는 POP3 메일을 읽거나 다룰 수 있도록 기능을 지원하는 소켓입니다. POP3 프로토콜은 전자우편(이메일)을 수신하기 위한 표준 프로토콜 중 하나입니다. 보통 일반적으로 Mac OS X 의 Mail 프로그램이나 MS Office 의 Entourage 와 같은 프로그램 POP3 를 지원합니다. 최근 메일을 보면 웹메일, POP3 방식으로 크게 2가지로 나누어질 수 있습니다. 웹메일은 말 그대로 웹브라우져를 통해서 보는 메일의 방식입니다. 반면 POP3 는 서버에서 자신의 컴퓨터로 메일을 가져와서 보는 방식이지요. 웹메일은 보는데에는 좀 불편할 수 있지만 항상 서버에 메일이 있기 때문에 언제 어디서든 인터넷 접속만 되면 볼 수 있다는 장점이 있습니다. 반면 POP3 방식의 메일 서비스는 메일을 받은 자신의 컴퓨터에서만 볼 수 있다는 점입니다. 항상 노트북을 갖고 다니거나 자신의 컴퓨터 작업 환경이 한군데에 위치한 사람들은 POP3 방식이 더욱 편리할 것이며 여기저기 플랫폼에 구애받지 않고 가볍게 메일을 보고 관리를 하기 위해서는 웹메일이 더 편리하겠죠. 웹 메일 같은 경우는 항상 인터넷을 접속해야 기존의 메일을 봐야한다는 것과 웹브라우져로 보다보니 필요없는 광고나 이미지들을 봐야하고 한번에 많은 내용을 보기도 힘들고 검색이 어렵다는 단점이 있는 반면에 POP3 는 서버에서 미리 메일을 가져오기 때문에 다른 컴퓨터에서는 볼 수 없다는 점과 받은 메일들을 자주자주 관리해줘야 한다는 점이 단점이 되겠죠. 그리고 시스템을 재설치하거나 할 경우 메일의 백업도 문제가 될 수 있습니다. 하지만 양쪽 메일 서비스 모두 각각의 장단점 특성이 있기 때문에 메일 아이디나 작업에 따라 웹메일과 POP3 메일 서비스를 동시에 이용하는 사람들이 많습니다. 리얼베이직에서는 POP3 프로토콜을 손쉽게 사용하기 위해서 제공하는 것이 바로 POP3Socket 입니다. POP3Socket 클래스를 이용하지 않고 TCPSocket 만을 이용하여 POP3Socket 을 구현하는 것은 가능합니다. 하지만 서버의 응답에 따른 명령어를 하나하나 다 해야하고 그에 따르는 반응에 대한 이벤트도 별도로 구성을 해줘야합니다. POP3 프로토콜은 다른 프로토콜에 비해서 많이 복잡하지는 않기 때문에 구현하는데 좀 더 수월하지만 기본으로 제공을 해주는 POP3Socket 클래스를 이용하면 훨신 더 간편하게 POP3 프로토콜 서비스를 이용할 수 있습니다. 그럼 POP3Socket 클래스에 대해서 공부해보도록 하겠습니다.

a. POP3Socket 에 대해서.
그럼 메일 프로토콜을 지원하는 리얼베이직의 POP3Socket 클래스에 대해서 상세하게 알아보도록 하겠습니다.

- 속성(Properties)
POP3Socket 의 속성은 아주 간단합니다. 다음의 내용들이 속성이며 대신 SocketCore 의 하위 클래스이기 때문에 SocketCore 클래스가 갖고 있는 속성 역시 그대로 사용할 수 있습니다.

*참조 : 온라인 도움말의 SocketCore Class
*참조 : POP3 프로토콜에 대한 명령어 및 설명은 RFC 1939 문서를 참조하시기 바랍니다. 이는 인터넷 검색 사이트에서 "RFC 1939" 를 찾으면 금방 찾으실 수 있습니다.
* Username : 기본적으로 웹메일 이용시에도 자신의 아이디와 암호를 필요로 합니다. POP3 프로토콜 역시 아이디와 암호가 있어야만 해당 아이디에 해당되는 메일들을 가져올 수 있습니다. 따라서 POP3Socket 에서의 기본 속성중 POP3 프로토콜 접속이후 인증에 필요한 ID 가 바로 UserName 이 됩니다. Username 속성에 올바른 아이디가 들어가 있어야만 POP3 서버로부터 해당 아이디의 메일을 가져올 수 있습니다. 데이타 타입은 유저명을 기록해야하기 때문에 당연히 문자형인 String 타입입니다.
* Password : UserName 속성에 해당되는 올바른 암호를 나타내는 속성입니다. 암호가 틀리면 아무리 아이디가 많아도 소용이 없겠죠? Password 속성의 데이타 타입 역시 username 과 동일하게 문자형인 String 타입입니다.
* EncryptPassword : 이 속성은 참과 거짓을 나타내는 Boolean 형의 데이타 타입을 갖습니다. 이 속성 값이 True 이면 Password 속성이 암호화 되어 서버에 전송이 됩니다.
* Address : 온라인 도움말에는 없지만 기본 SocketCore 에는 있는 속성입니다. 보통 도메인 명이나 IP 주소를 적게 되는데 물론 그렇게 해도 되지만 일반적인 POP3 메일 서버의 이름은 mail.x.x 식으로 기록하게 됩니다. 이런식의 POP3 메일 서버 주소를 적어주면 됩니다.
* Port : 이 속성 역시 온라인 도움말에는 없지만 SocketCore 에 있는 속성이기 때문에 POP3Socket 클래스에서도 사용이 됩니다. POP3 프로토콜이 사용하는 Port 는 110번입니다. 따라서 110번으로 Port 속성을 지정해줘야 합니다.

다음은 POP3Socket 클래스를 이용하여 POP3 메일 서버에 접속할 때 사용되는 처음 속성을 지정해주는 코드 입니다. 다음의 코드 내용을 보면 위의 속성들이 쉽게 이해가 갈 것입니다.
MyPOP3Socket.Address = "mail.shinbiro.com" //메일 서버 주소
MyPOP3Socket.port = 110 //기본 POP3 프로토콜의 Port
MyPOP3Socket.UserName = "michelin" //POP3 메일 서버에 로긴하기 위한 아이디 지정
MyPOP3Socket.Password = "XXXXXXXX" //암호 지정
MyPOP3Socket.Connect //접속 명령어
위의 코드 내용은 필자의 Shinbiro 메일 서버의 계정입니다. 신비로 메일 서버에 접속을 하려면 위와 같은 방식으로 하게 되죠. 다른 서버에 접속시에는 Address 속성의 주소를 해당 서버 주소로 변경하고 아이디와 암호를 해당 서버에 등록된 내용으로 적으면 POP3 서버에 접속할 수 있습니다. 서버에 접속만 한다고 해서 모든 것이 다 해결이 되는 것은 아닙니다. 다음의 함수들을 이용하여 적절을 명령어를 서버에 전송을 해주어야 올바른 메일 내용을 가져올 수 있습니다. 그럼 함수에 대해서 알아보도록 하죠.

- 함수(Methods)
POP3Socket 클래스는 다양한 함수를 갖고 있습니다. 왜냐하면 POP3 프로토콜의 역할을 해주는 명령어를 함수단에서 모두 처리를 해주고 있기 때문입니다. POP3 의 기본 함수는 메일의 카운트를 체크해주는 STAT 명령어외 메일 내용이나 삭제를 하는 LIST, DELE 등의 12가지 명령어가 있습니다. 따라서 이러한 작업을 모두 해주기 위해서는 해당되는 함수들이 많이 존재해야하기 때문에 기본 SocketCore 클래스에 포함된 함수외에도 POP3 메일 서버에서 메일 정보를 가져오기 위한 다양한 함수들이 존재합니다. 그럼 자세히 알아보도록 하죠.

* CheckServerConnection : 이름 그대로 서버의 접속 상태를 확인하는 함수입니다. 이 함수는 실질적으로 서버에 POP3 명령어중 하나인 "NOOP" 명령어를 보내게 됩니다. NOOP 명령어와 같은 동작을 하는 것이죠. 이 함수는 한참동안 작업이 없을 경우 서버의 접속이 이루어졌는지를 확인하는데 사용됩니다. 일정기간이 지나게 되면 접속이 끊길 수도 있기 때문이지요.
* Connect : POP3 메일 서버에 접속하게 됩니다. 원래 POP3Socket 을 사용하지 않고 기본 TCPSocket 을 이용하여 Connect 함수를 통해 접속을 하게되면 서버로 부터 "connect" 라는 메세지가 뜨게 됩니다. 이때에 "USER" 명령어를 통해 UserName 을 보내게 되면 서버로 부터 "USER"라는 메세지가 전송되게 되죠. 마지막으로 "PASS" 명령어를 통해 Password 를 보내게 되면 접속 이후 인증이 완료되게 됩니다. POP3Socket 에서는 이러한 3가지 작업을 Username, Password 속성과 connect 함수를 통해서 한번에 해결을 해줍니다.
* CountMessages : 이 함수는 서버에 인증된 아이디에 포함된 메세지가 현재 몇개가 존재하고 있는지를 확인해주는 함수입니다. 이 함수는 서버에 "STAT" 명령어를 전송하게 되어 서버로 부터 메일의 갯수를 알려주도록 하죠. 이 함수를 사용했을 때 뒤에 배울 MessageCount 이벤트를 통해서 메일의 갯수가 전송되게 됩니다. MessageCount 이벤트에 대해서는 뒤에 이벤트에서 다시 한번 알아볼 것입니다.
* DeleteMessage : 이 함수는 말 그대로 서버의 지정된 메일을 지워주는 함수입니다. 해당 메일은 순서대로 기록이 되어있기 때문에 메일을 지정하는 정수형의 Index 값을 인수로 사용합니다. MyPOP3Socket.DeleteMessage 1 이라고 하면 1번째의 메일이 삭제될 것입니다. 메일이 삭제되면 지워진 해당 인덱스 값을 인수로 하는 MessageDeleted 이벤트가 발생됩니다. MessageDeleted 이벤트에 대해서도 뒤에가서 공부해보도록 하죠.
* DisconnectFromServer : 이 함수는 POP3 메일 서버로부터 접속을 해제할 때 사용됩니다. 이 함수는 실질적으로 POP3 메일 서버에 "QUIT" 명령어를 보내게 되죠. QUIT 명령어는 POP3 프로토콜에서 접속을 끊는 명령어 입니다.
* ListMessage : 해당 메일의 인덱스와 메일 사이즈를 가져오게 됩니다. 사용하는 인수로는 메세지의 Index 값을 인수로 사용합니다. 인수를 사용하지 않고 함수만 실행할 수 있는데 이때에는 전체 메일을 가져오는 것으로 간주하고 전체 메일에 대한 인덱스와 메세지의 사이즈를 가져오게 됩니다. 이 함수를 이용하게 되면 POP3 메일서버에는 "LIST" 라는 명령어를 전송하는것과 동일한 결과를 가져오게 됩니다. ListMessage 함수가 실행되면 ListReceived 이벤트를 통해서 해당 메일의 인덱스 값과 메일 사이즈가 나오게 됩니다. 다음은 POP3Socket 을 통해서 필자의 메일 서버를 통해 ListMessage 를 이용한 후에 결과 값을 가져온 화면입니다. (그림보기)
* RetrieveLines : 이 함수는 정수형의 메세지인덱스 값과 LineCount 값을 사용합니다. 이 인수값들을 이용하여 해당 인덱스의 메세지의 해당 라인 카운트만큼의 메세지를 가져오게 됩니다. 즉 해당 라인 카운트 만큼 인덱스의 메세지를 가져오는 것입니다. RetrieveLines 함수가 실행되면 TopLinesRertived 이벤트가 실행이 되고 TopLinesRertived 이벤트에서 사용되는 인수 값을 이용하여 메일의 메세지를 확인할 수 있습니다.
* RollbackServer : 메일 서버를 로긴 상태로 변경해 놓는 함수 입니다. 쉽게 생각하면 Undo 명령어 처럼 생각할 수 있습니다. 변경된 사항은 POP3 메일 서버에 접속이 끊어지기 전까지는 유지가 되기 때문에 이러한 함수가 가능합니다. 이 함수는 POP3 프로토콜의 RSET 명령어와 동일한 기능을 합니다.
* SendServerCommand : 이 함수는 POP3 프로토콜에서 제공하는 명령어를 직접 입력하고 사용할 수 있습니다. 대부분의 주요 명령어가 POP3Socket 클래스에서 함수로써 제공을 해줍니다만 몇가지 제공이 안되는 것도 있습니다. 이렇게 아직 리얼베이직의 POP3Socket 클래스에서 제공해주지 않는 명령어를 사용할 때 사용되는 함수입니다.

- 이벤트
이번에는 POP3Socket 클래스의 이벤트에 대해서 알아보도록 하겠습니다. POP3Socket 클래스의 이벤트는 대부분 POP3Socket 클래스 함수를 실행하고 난 뒤에 발생하는 이벤트들입니다. POP3 메일 서버에 명령어가 전달이 되어 실행이 되면 그 명령어에 대한 응답 메세지가 오게 되는데 이를 내부적으로 받아서 알아서 처리하여 이벤트화 시킨 부분이 POP3Socket 클래스의 이벤트 입니다. 앞서 함수를 공부하면서 몇가지 이벤트들이 언급이 되었었습니다. 그럼 좀 더 자세히 공부를 해보도록 하죠.

* ConnectionEstablished : 이 이벤트는 접속이 이루어지면 발생하는 이벤트입니다. Connect 함수를 통해서 POP3 메일 서버에 접속이 되면 이 이벤트가 자동적으로 발생합니다. TCPSockt 콘트롤의 Connected 이벤트와 동일하다고 생각하시면 됩니다.
* Disconnected : POP3 메일 서버와 접속이 끊어지면 발생하는 이벤트 입니다. 이 이벤트는 DisconnectFromServer 함수에 의해서 POP3 메일 서버와 접속이 끊어지거나 기타 여러가지 에러 및 동작에 대한 무반응 이후 시간 초과로 접속이 끊어지게 되면 발생하는 이벤트 입니다. 보통 네트웍에서는 어떤 이유던 접속이 끊어지게 되면 해당 Error 코드가 발생하게 되는데 이는 TCPSocket 의 Error 이벤트에서 확인하는 것과 동일하다고 보시면 됩니다.
* ListReceived : 앞서 언급되었던 ListMessages 함수가 실행된 후 서버로부터 인덱스 ID 와 메일의 Bytes 사이즈가 전송이 될 때 발생하는 이벤트 입니다. 이 이벤트에는 List 라는 String 타입의 인수를 사용하게 되는데 이 List 인수 값에는 해당 인덱스와 사이즈 값이 들어있게 됩니다.
* LoginSuccessful : 네트웍 프로그램에서 주의할 점 중 하나는 접속과 인증은 다르다는 것입니다. 보통 로긴이라는 명칭을 사용하면서 접속까지 포함해서 말하는 경우가 있는데 접속은 서버에 접속이 되기만 하면 이루어 지는 것이 접속입니다. 실질적인 로긴과 같은 작업이 인증 작업이라고 볼 수 있는데 보통의 인증은 아이디와 암호를 입력하여 통과하는 테스트 관문 같은것이라고 생각을 하면 되겠죠. 따라서 접속을 되었다 하더라도 제대로 인증을 하지 못하면 접속한 서버의 기능을 하나도 활용할 수 없게 되는 것입니다. LoginSucessful 이벤트는 아이디와 암호를 통해서 올바르게 인증이 되면 발생하는 이벤트 입니다. 앞서 Connect 함수를 설명하면서 자세히 설명을 한것처럼 POP3Socket 클래스는 UserName 속성과 Password 속성을 이용하여 손쉽게 접속과 인증과정을 실행해 줍니다. 그리고 인증이 성공적으로 끝나게 되면 LoginSucessful 이벤트가 발생하게 되는 것입니다.
* MessageCount : POP3Socket 클래스의 CountMessages 함수가 실행이 되면 발생이 되는 이벤트 입니다. 이 이벤트는 Count 라는 정수형 인수를 받아들입니다. 이 Count 값이 실질적으로 POP3 메일 서버에 있는 메세지의 갯수를 말합니다.
* MessageDeleted : POP3Socket 클래스의 DeleteMessage 함수가 실행 된 후 제대로 삭제가 되면 MessageDeleted 이벤트가 실행이 되고 삭제된 인덱스 아이디가 인수로 넘어오게 됩니다.
* MessageReceived : POP3Socket 클래스의 ReceiveMessage 함수가 실행이 된 후에 메일의 메세지가 들어오게 되면 이 이벤트가 발생하게 됩니다. 이벤트가 발생하면서 같이 들어오는 인수로는 메세지의 Index 값과 EmailMessage 클래스 타입의 Email 내용이 들어오게 됩니다.
* 참조 : EmailMessage 클래스에 대한 자세한 내용은 온라인 도움말 참조
* RollbackSuccessful : POP3Socket 클래스의 RollbackServer 함수가 실행되고 난 후에 RollBack 이 완료 되었을 경우 발생하는 이벤트 입니다.
* ServerAvailable : POP3Socket 클래스의 CheckServerConnection 이벤트가 실행되고 나면 발생하는 이벤트입니다. 이 이벤트가 발생하면 POP3 메일 서버와의 접속은 제대로 이루어져있는 상태를 말합니다.
* ServerCommandReply : POP3Socket 클래스의 SendServerCommand 함수가 실행되고 나면 발생하는 이벤트 입니다. 이 이벤트에는 SendServerCommand 함수에서 인수로 사용했었던 명령어내용와 데이타가 인수로 전송이 됩니다.
* ServerError : POP3 프로토콜과 관련된 에러가 발생하는 발생되는 이벤트입니다. 이 이벤트에서는 ErrorCode dhk ErrorMessage, MessageID 를 인수값으로 받아들이게 됩니다. 발생하는 에러 코드는 다음과 같습니다.
0 - 알수없는 에러(Unknown Error Message)
1 - 암호가 틀림(Incorrect Password)
2 - 로긴 유저명이 틀림(Incorrect Username)
3 - 메세지를 삭제하는데 실패(Delete Message Failed)
4 - 메세지의 리스트를 가져오는데 실패(List Messages Failed)
5 - 메세지의 라인 내용을 가져오는데 실패(Retrieve Lines Failed)
6 - 메세지를 가져오는데 실패(Retrieve Message Failed)

* TopLinesReceived : POP3Socket 클래스의 RetrieveLines 함수가 실행되고 나서 메세지가 들어오게 되면 발생하는 이벤트입니다. 이 이벤트에는 정수형의 메세지의 Index 값과 EmailMessage 클래스 타입의 Email 내용을 가져오게 됩니다.


그럼 앞서 배운 내용들을 기반으로 하여 간단한 예제를 통하여 다시 한번 이해를 해보도록 하겠습니다.

a. TCPSocket 예제.
TCPSocket 콘트롤은 리얼베이직의 네트웍 프로그래밍의 기본 콘트롤입니다. 따라서 이를 통해서 Client & Server 환경을 구현하여 어떻게 접속을 이루고 메세지를 전송할 수 있는지 확인해 보도록 하겠습니다. 이 예제를 해보면 어떻게 메신저나 네트웍 프로그램들이 구현이 되는지 쉽게 이해가 가실 것입니다. 재미있을 것 같지요? 그럼 시작해 볼까요?

- 프로그램의 동작
프로그램 동작은 서버와 클라이언트간에 채팅을 하는 프로그램이 될 것입니다. 서버에서 Listen 함수를 이용해서 다른 클라이언트가 접속할 수 있도록 할 것이며 접속된 클라이언트는 서버에 메세지를 보내게 되고 그 메세지는 서버창과 클라이언트 창에 다시 다타나게 됩니다. 채팅이란 것은 자신이 보낸 메세지도 자신이 볼 수 있어야 하기 때문이지요. 당연히 서버쪽에서도 클라이언트에게 메세지를 보낼 수 있으며 이 역시도 서버 화면과 클라이언트 화면에서 동시에 보이게 됩니다. 이번 예제에서 좀 신경 쓸 부분은 한글에 관한 Encoding 관련 부분입니다. 기능상이야 어차피 데이타를 보내고 받는 부분이기 때문에 익숙해지면 쉽게 이해하고 구현할 수 있지만 그때그때 마다 깨지는 한글은 제대로 표현하기가 어려울 수 있습니다.

5.x 이전 버젼에서는 리얼베이직 자체가 한글을 사용시에 완성형 2바이트 한글만 사용했기 때문에 크게 문제가 되지 않을 수 있었지만 5.x 이상 버젼에서는 유니코드를 지원하기 시작하여 한글 코드 변환이 굉장히 까다로와 졌습니다. 따라서 이 예제에서는 소켓을 통해서 데이타를 전송할 때 한글이 깨지지 않게 하는지에 대한 방법도 공부할 수 있을 것입니다. 채팅을 기본으로 하는 메신저 같은 소프트웨어를 개발한다고 할 경우에 어떤 기능보다도 메세지를 제대로 표현해주는 것이 제일 우선이 되어야 하기 때문에 한글 코드 변환 부분의 내용은 반드시 숙지하시기 바랍니다. 솔직히 저도 한글을 텍스트 파일로 저장할 때에나 기타 여러 작업을 할 경우 가장 골치아프게 신경써야 하는 부분중 하나가 바로 한글코드이기 때문입니다.

- 인터페이스 구성
우선 채팅 프로그램이라 하면 메신저 같은 것을 생각할 수 있겠지만 이번 예제에서는 하나의 컴퓨터에서 구현을 하는 것이기 때문에 클라이언트와 서버의 채팅 화면을 하나의 윈도우에 모두 구현을 했습니다. 물론 완성된 프로그램에서는 다른 컴퓨터를 갖고 있는 유저들기리도 주소와 포트만 알면 서로 접속할 수 있게 되어있으니 일단 예제를 따라해보시기 바랍니다. 그리고 들어가야 할 콘트롤들이 다른 예제들 보다 많기 때문에 하나하나 구분해서 지정을 잘해 주시기 바랍니다. 먼저 첫번째로 리얼베이직을 실행시킨 후에 프로젝트 윈도우에 기본적으로 포함되어있는 Window1 을 선택합니다.
그럼 Name 속성을 "ChatWin"으로 바꾸어 줍니다. 그리고 Name 속성을 변경한 ChatWin 의 Width 속성과 Height 속성을 각각 800과 420으로 설정합니다. 또한 Title 속성을 "Chatting Window"로 설정합니다.

이제 넓직한 윈도우를 만들었으니 그 안에 내용을 채워 넣습니다. 먼저 Client 와 Server 사이를 쉽게 구분할 수 있도록 GroupBox 콘트롤을 양쪽에 2개식 위치시킵니다. 그리고 생성된 GroupBox1 콘트롤을 선택하고 속성윈도우에서 Name 속성을 "ClientGroupBox" 로 설정을 하고 Caption 속성 "Client"로 설정합니다.

또한 GroupBox2 콘트롤의 Name 속성은 "ServerGroupBox" 로 설정을 하고 Caption 속성은 "Server" 설정합니다.

이제 먼저 Client 의 세부 인터페이스를 만들어 보도록 합니다. 먼저 접속할 수 있는 Address 필드와 Port 필드를 만들고 접속 버튼을 만들도록 합니다. 그를 위해서 먼저 StaticText 콘트롤을 Client GroupBox 의 왼쪽 상단에 위치시키고 생성된 StaticText1 콘트롤의 Caption 속성을 "Address" 로 설정합니다. 그리고 두번째 StaticText 콘트롤을 만들고 Caption 속성을 Address 로 설정한 StaticText1 콘트롤의 바로 밑에 위치시킵니다. 그리고 Caption 속성을 "Port" 로 설정합니다. 그리고 이번에는 "Address"로 Caption 을 서정한 StaticText 콘트롤 오른쪽 부분에 EditField 콘트롤을 하나 배치시킵니다. 그리고 이 EditField 콘트롤의 Name 속성을 "ClientAddressField" 로 설정합니다. 그리고 Width 속성을 130으로 설정을 해서 가로 폭을 적절하게 조정해 줍니다. 이 EditField 콘트롤은 접속할 서버의 주소를 기록하기 위한 필드가 될 것입니다.

이번에는 ClientAddressField 하단 부분이고 Caption 속성을 "Port" 로 설정한 StaticText 콘트롤 오른쪽 부분에 서버에 접속할 Socket 의 Port 속성을 입력할 필드를 하나 배치 시킵니다. 이 역시도 EditField 콘트롤을 사용하면 됩니다. 그리고 이 EditField 콘트롤의 Name 속성을 "ClientPortField" 로 설정합니다. 그리고 매번 입력을 피하기 위해서 EditField 의 기본 Text 속성을 "9976" 이라고 정합니다. 이 포트 번호는 단순 테스트를 하기 위함이기 때문에 1024 이상의 포트 번호를 임의로 사용하셔도 됩니다.

이제는 접속을 위한 Connect 버튼을 만들어 보도록 하겠습니다. 이는 PushButton 콘트롤을 이용하였습니다. PushButton 콘트롤을 툴바에서 드래그 하여 좀 전에 생성했었던 ClientAddressField 의 오른쪽 부분에 배치를 시킵니다. 그리고 Name 속성을 "ConnectButton" 으로 설정합니다. 또한 Caption 속성은 "Connect"로 하고 Width 속성을 100 정도로 설정합니다. 이 버튼은 이름 그대로 서버에 접속을 할 때 눌려지는 버튼이며 접속이 되면 Caption 속성이 자동으로 "Disconnect" 로 바뀌도록 할 것입니다.

이제 기본적인 접속을 위한 인터페이스는 마련이 되었습니다. Client 의 접속 부분에 대한 완성된 인터페이스는 다음 처럼 구성을 하시면 됩니다.


이제는 채팅을 위한 메세지 부분을 확인해 보도록 하겠습니다. 채팅을 위해서 기본적으로 생각을 해보면 2가지가 필요합니다. 한가지는 메세지를 보여주는 부분이고 또 한가지는 메세지를 작성해서 보내는 부분이 되겠죠. 이 2가지 모두 EditField 콘트롤을 이용하여 구현하시면 됩니다. 먼저 채팅 메세지를 보여줄 수 있는 메세지 창 부분을 만들어 보도록 하죠.

툴바에서 EditField 콘트롤을 드래그 하여 앞서 구성했었던 접속 인터페이스 하단에 위치시킵니다. 그리고 Name 속성을 "ClientMessageField"로 설정합니다. 그리고 Width 와 Height 속성을 각각 328 과 230으로 설정합니다. 마지막으로는 ReadOnly 속성을 True 로 설정합니다. 이는 메세지 창의 내용은 보거나 복사만 할 수 있도록하고 따로 메세지를 작성할 수 없도록 하기 위함입니다.

ClientMessageField 를 구성했으면 이제 메세지를 타이핑하여 작성하고 보낼 수 있는 입력 필드를 만들어 보도록 합니다. 다시 한번 EditField 콘트롤을 이용하여 앞서 만들었던 ClientMessageField 의 바로 밑 하단 부분에 배치 시킵니다. 그리고 Name 속성을 "ClientChatField" 로 지정을 해 줍니다.
또한 Width 속성을 328 정도로 설정합니다.

이제는 Client 부분의 인터페이스 구성의 마지막 부분으로 TCPSocket 콘트롤을 배치하도록 합니다. 단순히 툴바에서 TCPSocket 콘트롤을 선택한 뒤에 윈도우의 임의의 부분에 드래그 해 놓으면 됩니다. 구분하기 쉽게 ClientGroupBox 콘트롤 안에 배치시켜보도록 합니다. 그리고 Name 속성을 "ClientTCPSocket" 으로 설정합니다.


원래 TCPSocket 의 Port 나 Address 속성을 속성윈도우에서도 지정할 수 있으나 이는 앞서 만들었던 ClientAddressField 와 ClientPortField 의 값을 통해서 받아들일 것이기 때문에 Name 속성만을 지정했습니다. 그리고 이는 코드 작성시에 구현을 할 것입니다.

그럼 완성된 Client 채팅 화면을 확인해 보시기 바랍니다.


이제는 서버 부분의 인터페이스를 설정 해보도록 합니다.

서버쪽에서는 Client 부분과는 다르게 주소를 입력할 필요가 없습니다. 왜냐하면 자신의 컴퓨터에 할당된 주소를 사용하게 되기 때문이지요. 서버의 주소 할당 부분은 코드작성시에 할당할 수 있으니 그때 다시 보도록 합니다. 따라서 서버쪽에서는 Port 만 지정하여 입력하는 부분을 만들어 보도록 합니다.

Client 인터페이스에서 Port 인터페이스를 만들었던 것 처럼 StaticText 콘트롤을 이용해서 ServerGroupBox 콘트롤 내의 왼쪽 상단에 위치시키고 Caption 속성을 "Port"로 지정합니다.

기본적으로 화면에 나타내기 위한 방법으로는 StaticText 콘트롤을 이런식으로 많이 사용합니다. 그때에는 특별히 Name 속성을 지정할 필요도 없고 Caption 부분만 지정해서 간단하게 표시를 해주면 됩니다. 화면에 텍스트를 나타내기 위한 가장 간단하면서도 깔금한 방법이라 할 수 있습니다. 여튼 위와 같이 하고 나서 이제는 실질적으로 Server 의 포트를 설정하기 위한 CientPortField 와 동일한 기능을 하는 Port 입력 필드를 만들어줍니다. Port 텍스트 오른쪽에 위치시키면 되고 ClientPortField 와 모두 동일하게 하되 Name 속성은 "ServerPortField" 로 설정해 줍니다.


이번에는 접속 상태를 나타내는 부분을 만들어 보도록 하겠습니다. 이것은 StaticText 콘트롤을 이용하여 Client 가 접속을 하게 되면 "Connect" 라고 표시를 하고 접속이 끊어져 있으면 "none"라고 표시를 해서 Client 의 접속상태를 나타나게 할 것 입니다. 이미 앞서 리얼베이직의 Graphics 에 대해서 공부했기 때문에 어느정도 익숙해 지신 분들은 이러한 접속 표시를 텍스트로 표현할 필요 없이 그림 이미지로 표현을 해도 괜찮겠습니다. 여튼 이제 다시 한번 StaticText 콘트롤을 툴바에서 드래그 하여 앞서 만든 ServerGroupBox 콘트롤 내의 만든 Port StaticText 콘트롤 하단에 위치시킵니다. 그리고 Name 속성을 "InfoText" 로 설정 해줍니다. 그리고 기본 Text 속성을 "none"으로 설정합니다.

이제는 접속 대기상태로 만들기 위한 버튼을 만들어 보도록 합니다. Client 부분에서 만들었던 Connect 버튼과는 좀 다르게 Server 쪽의 버튼은 Server 가 Client 의 접속을 받아들이기 위한 준비를 하는 버튼입니다. 이러한 기능은 TCPSocket 의 Listen 함수를 통해서 가능합니다. 사용법은 앞서 배운 것 처럼 단순히 포트를 정의하고 Listen 함수만 사용하면 됩니다. 이 부분도 인터페이스를 만든 이후에 코드 작성 부분에서 확인토록 하겠습니다. 우선 PushButton 콘트롤을 앞서 만든 ServerPortField 콘트롤의 오른쪽에 위치시킵니다. 그리고 Name 속성을 "ListenButton"으로 설정합니다. 또한 기본 Caption 속성을 "Listen" 을 설정해 놓습니다.

그럼 이번에는 Client 부분처럼 메세지 채팅 필드를 만들 차례 입니다. 이번에도 똑같이 메세지를 보여주는 부분과 메세지를 작성하고 보내는 부분 2가지를 EditField 콘트로을 이용해서 구성을 해서 만들 것 입니다. 우선 먼저 메세지를 보여주는 필드를 만들어 보도록 하겠습니다. 툴바에서 EditField 콘트롤을 선택한 뒤에 드래그 하여 ServerGroupBox 콘트롤 내에 위치시키고 Client 부분에서 만든것과 같이 배치를 시킵니다. 그리고 Name 속성은 "ServerMessageField" 로 지정합니다. 그리고 Width 와 Height 속성을 각각 328, 230 으로 설정합니다. 또한 ClientMessageField 와 동일하게 ReadOnly 속성을 True로 설정합니다.

그리고 이제는 메세지를 작성하고 보내는 ChatField 를 만들어 보도록 합니다. 이 역시 Client 파트와 동일하게 EditField 콘트롤을 이용해서 ServerMessageField 의 하단에 위치를 시킵니다. 그리고 Name 속성을 "ServerChatField" 로 설정하고 Width 속성을 328로 설정합니다.
그리고 마지막으로 Server 가 사용할 TCPSocket 콘트롤을 드래그 하여 ServerGroupBox 콘트롤 내의 임의의 위치에 배치시키고 Name 속성을 "ServerTCPSocket" 로 설정합니다.

긴 인터페이스 만드시느라 수고 많으셨습니다. 이제 인터페이스는 모두 완성이 됐습니다. 완성된 인터페이스는 다음과 같습니다. 한번 직접 만드신 인터페이스와 비교를 해보시기 바랍니다.

- 코드 작성
인터페이스에서 보면 알다시피 왼쪽이 클라이언트가 되고 오른쪽이 서버 부분이 됩니다. 그리고 오른쪽의 서버 부분에서 클라이언트가 접속할 수 있도록 Listen 이 설정이 되면 왼쪽의 클라이언트에서는 ClientAddressField 의 주소와 Port 값을 이용하여 접속이 되도록 합니다. 같은 화면에 같은 프로그램이라 하더라도 내부적으로는 직접 TCPSocket 콘트롤을 이용하여 접속을 하고 채팅 메세지를 주고 받도록 기능을 추가할 것입니다. 또한 같은 프로그램도 아니고 다른 컴퓨터에 있다하더라도 서버쪽의 아이피를 알고 포트만 맞추면 위의 예제로 서로 채팅할 수 있도록 구성을 할 것입니다. 그럼 위와 같은 기능이 가능하도록 이제부터 코드를 작성해 보도록 하죠.

먼저 ChatWin 을 더블클릭하여 코드에디터가 활성화 하게 만듭니다. 그리고 ChatWin 의 Open 이벤트 부분에 다음과 같은 코드를 작성합니다.
ClientAddressField.Text = ClientTCPSocket.LocalAddress
위의 코드는 ClientAddressField 콘트롤의 Text 속성에 현 컴퓨터의 주소를 미리 프로그램이 시작될 때 입력을 해주는 것입니다. 이는 테스트를 손쉽게 하기 위해서 매번 주소를 입력하기 싫어서 해놓은 기능입니다..^^;; 같은 컴퓨터내에서 동작하는 서버이기 때문에 주소는 같게 되는 것이기 때문이지요.
여튼 여기에서 주의깊게 봐야할 점은 TCPSocket 의 LocalAddress 속성입니다. 이 속성은 자기 자신의 IP 주소를 가져와야할 경우 위와 같은 방법으로 자신의 IP를 구할 수 있습니다. 자신의 매킨토시 아이피를 보여줘야하는 경우에는 위와 같은 방법으로 구현을 하시기 바랍니다. 가장 간단하고 가장 쉬운 방법중 하나입니다..^^;;

그리고 나중에 작성해도 되는 코드이지만 미리 작성을 해두도록 하죠. ChatWin 의 Close 이벤트에 "Quit" 라는 코드를 작성합니다. 이 코드는 ChatWin 을 닫으면 자동으로 종료가 되도록 하는 코드입니다. 그래서 Close 이벤트에 작성을 했습니다.

그럼 이제 본격적인 Socket 부분에 코드를 작성해 보도록 하겠습니다. 먼저 Server 부분을 보도록 합니다. 서버쪽 인터페이스에서 ListenButton 만든 것 기억하시죠? 그 버튼을 더블클릭합니다. 그리고 Action 이벤트에 다음과 같은 코드를 작성합니다.
dim Port as Integer

if me.Caption = "Listen" then
Port = val(ServerPortField.text)

ServerTCPSocket.Port = Port

ServerTCPSocket.Listen

me.Caption = "Close"
else
ServerTCPSocket.Close
me.Caption = "Listen"
InfoText.text = "none"
end if
위의 코드는 먼저 ListenButton 의 Caption 속성을 이용하여 그에 따라 2가지 동작을 하도록 하였습니다. 처음에는 Caption 이 "Listen"으로 설정이 되도록 인터페이스를 만들었었습니다. 그 Caption 값을 If 문을 이용하여 "Listen" 이만 ServerTCPSocket 이 Listen 함수를 이용하여 접속 대기 상태가 되도록 설정을 하였습니다. 그 부분의 코드가 다음과 같습니다.
Port = val(ServerPortField.text)

ServerTCPSocket.Port = Port

ServerTCPSocket.Listen

me.Caption = "Close"
여기에서 Port 라는 Integer 형 변수는 ServerPortField 의 Text 속성을 이용하여 포트 값을 가져온 뒤에 ServerTCPSockt 의 Port 속성에 대입을 하도록 하였습니다. 초기 포트는 인터페이스에서 만들었던 것 처럼 "9976" 번으로 하였습니다. 이 포트 번호는 1024 이상의 포트 번호를 사용할 경우 여러분들 임의대로 설정할 수 있다는 것을 기억해주시기 바랍니다. ServerTCPSocket.Listen 코드가 바로 ServerTCPSocket 을 접속 대기 상태로 만들어 주는 코드입니다. 그리고 바로 me.Caption = "Close" 코드를 통해서 ListenButton 의 Caption 속성을 "Close" 로 바꾸어 주었습니다. ListenButton 의 Caption 속성이 "Listen" 이 아니면 다음과 같은 코드를 실행하도록 If 문이 되어있습니다.
ServerTCPSocket.Close
me.Caption = "Listen"
InfoText.text = "none"
위의 코드는 TCPSocket 의 Close 함수를 이용하여 현재 접속 대기 상태로 열려있는 erverTCPSocke 을 닫아주는 역할을 합니다. 물론 클라이언트가 접속이 되어있어도 접속은 끊기게 되죠. 이럴 경우 접속된 클라이언트 쪽에서는 ConnectDrop 이라는 에러메세지를 받고 서버쪽에서 접속을 차단한것으로 알고 클라이언트의 소켓 접속도 차단하게 됩니다.

그럼 이번에는 ClientConnectButton 에 코드를 작성해 보도록 하죠. 이 버튼에는 ClientAddressField 의 Text 속성을 이용해서 주소를 가져오고 그 주소를 다시 ClientTCPSocket 의 Address 속성에 대입하여 접속할 서버의 주소를 설정하는 코드가 작성이 됩니다. 물론 ClientPortField 를 통해서 사용하는 유효 포트번호를 가져오고 이것도 ClientTCPSocket 의 Port 속성에 대입을 하게 되죠. 그리고 마지막으로 ClientTCPSocket 의 Connect 함수를 이용해서 서버에 접속을 하게 됩니다. 위의 동작에 따라 작성된 코드는 다음과 같습니다.

dim Address as String
dim Port as Integer

if me.Caption = "Connect" then

Address = ClientAddressField.text
Port = val(ClientPortField.text)

ClientTCPSocket.Address = Address
ClientTCPSocket.Port = Port

ClientTCPSocket.Connect

elseif me.Caption = "Disconnect" then
ClientTCPSocket.Close
me.Caption = "Connect"
end if

위의 코드를 보시면 알다시피 앞서 좀전에 설명한 내용그대로 순서대로 코드가 작성된 것을 확인할 수 있습니다. 여기에서 좀 더 주의 깊게 봐야할 점이 If 조건 문입니다. Caption 속성을 체크해서 ConnectButton 콘트롤의 Caption 속성이 "Connect" 이면 접속 코드를 실행을 하게 됩니다. 그 코드는 바로 아래의 코드 입니다.

Address = ClientAddressField.text
Port = val(ClientPortField.text)

ClientTCPSocket.Address = Address
ClientTCPSocket.Port = Port

ClientTCPSocket.Connect

앞서 설명한 내용 그대로 작성이 된 것이죠. 주소와 포토 값을 가져와서 Connect 함수를 이용하여 네트웍 접속을 이루도록 해주는 코드 입니다. 그리고 ConnectButton 콘트롤의 Caption 속성이 "Disconnect" 이면 접속을 끊는 코드를 실행하는 부분이 If 절에 작성이 되어있지요. 그 코드는 다음과 같습니다.

ClientTCPSocket.Close
me.Caption = "Connect"

ClientTCPSocket 콘트롤의 Close 함수를 통해서 Client 가 Server 의 연결을 해제하도록 한 코드 입니다. 연결이 끊어지도록 Close 함수를 이용한 뒤 ConnectButton 의 Caption 속성을 "Connect" 로 다시 바꾸어서 이후에 다시 버튼을 누르면 접속이 되도록 설정한 코드 입니다. ConnectButton 콘트롤의 Caption 속성을 "Disconnect"로 바꾸어주는 부분은 바로 다음에 작성할 ClientTCPSocket 의 Connected 이벤트 부분이 됩니다. 그럼 이제 ClientTCPSocket 의 Connected 이벤트 부분에 다음과 같은 코드를 작성해 보도록 하죠.

ConnectButton.Caption = "Disconnect"

위의 코드는 ClientTCPSocket 콘트롤이 서버에 접속이 되면 발생하는 이벤트인 "Connected" 이벤트가 발생하면 실행되는 코드입니다. ConnectButton 의 Caption 속성을 "Disconnect" 로 바꾸어서 버튼의 표시를 "Disconnect"로 나타나게 하는 것이죠. Caption 속성이 "Disconnect" 이면 접속을 끊어주는 역할을 하게 됩니다. 이는 앞서 ConnectButton 의 Action 이벤트에서 작성된 코드 중 If 절의 2번째 구문을 봤기 때문에 이해가 되실 겁니다.

그럼 이번에는 Client 에서 Server 쪽으로 접속이 되었을 경우에 처리 되는 Server 의 Connected 이벤트의 코드를 확인해 보도록 하죠. ServerTCPSocket 콘트롤의 Connected 이벤트에 다음과 같은 코드를 작성해 봅니다.

InfoText.text = "Connected"

단 한줄입니다. 단지 클라이언트가 접속이 되었다는것을 InfoText 콘트롤을 통해서 알려주는 것입니다.

그럼 이제 데이타를 처리하기 전에 먼저 Error 처리 부분을 보도록 하겠습니다. 보통 TCPSocket 콘트롤에서 Error 이벤트 부분이 발생하게 되면 대부분 접속이 끊어지게 됩니다. 정확히 하려면 발생하는 에러 코드에 따라 코드를 처리해야하겠지만 간단한 예제이기 때문에 간단하게 코드를 작성하였습니다. ClientTCPSocket 콘트롤의 Error 이벤트에는 다음과 같이 처리를 하였습니다.

ConnectButton.Caption = "Connect"

에러가 발생하여 접속이 끊어지면 ConnectButton 의 Caption 속성을 "Connect" 으로 바꾸어주는 코드입니다. ServerTCPSocket 콘트롤의 Error 이벤트에는 다음과 같이 처리를 하였습니다.

InfoText.text = "none"
ListenButton.Caption = "Listen"

이 역시도 에러가 떨어져서 접속이 끊어지게 되면 InfoText 의 Text 속성은 처음 프로그램을 실행했을 때 처럼 "none" 으로 바뀌도록 하였고 ListenButton 의 Caption 속성도 "Listen" 으로 바뀌도록 하였습니다.

*좀 더 정확한 에러 처리를 위해서는 앞서 배웠던 TCPSocket 과 SocketCore 클래스의 ErrorCode 속성을 확인하여 Select Case 조건문이나 If 조건문을 이용하여 에러 처리를 하면 될 것입니다.

이제 접속과 에러 처리부분도 끝났으니 가장 중요한 부분인 데이타를 처리하는 부분에 대해서 알아보도록 하겠습니다. 접속은 되었다라는 가정하에 코드를 작성해 보도록 하겠습니다. 접속이 되면 바로 채팅이 가능하게 됩니다. 따라서 먼저 Client 부분의 ClientChatField 콘트롤에서 메세지를 입력하면 Server 쪽으로 메세지가 전송이 되고 서버의 Message 창과 Client 의 메세지 창에 채팅 내용이 나타나게 될 것 입니다. 그럼 먼저 ClientChatField 부분에서 메세지를 보내는 코드를 작성해 보도록 하겠습니다. ClientChatField 콘트롤의 KeyDown 이벤트 부분에 다음과 같은 코드를 작성해 보도록 합니다.

dim Message, Temp as String

if key = chr(13) then

Message = ClientChatField.text

Temp = "CHAT"+chr(9)+Message+EndOfLine
Temp = ConvertEncoding(Temp, Encodings.MacKorean)

ClientTCPSocket.Write Temp

ClientChatField.text = ""

end if

위의 코드는 ClientChatField 콘트롤에 입력되는 Text 내용을 가져와서 ClientTCPSocket 으로 보내는 코드입니다. 먼저 주의할점은 코드를 보내기 전에 ConvertEncodings 함수를 통해서 코드 변환을 해준다는 것이죠. 먼저 Socket 을 통해 보낼 데이타를 구성하고 이 내용들의 코드를 변환을 해줍니다. 물론 1바이트 영문권이라면 이런 작업을 할 필요가 없겠지만 2바이트 언어권에서는 이러한 코드 변환작업을 해야합니다. 그래서 다음과 같이 해야 한글이 깨지지 않고 제대로 나타날 것이빈다.

Temp = "CHAT"+chr(9)+Message+EndOfLine
Temp = ConvertEncoding(Temp, Encodings.MacKorean)

그리고 ClientTCPSocket 의 Write 함수를 통해서 변환된 코드 내용인 Temp 내용을 네트웍을 통해 보내게 되죠. 그런데 여기에서 눈여겨 볼 점은 보내는 매세지의 첫번째 부분에 "CHAT" 이라고 지정을 해주었다는 것입니다. 이 부분은 메세지의 종류를 구분하기 위한 것입니다. 물론 이 예제처럼 간단한 것에서는 크게 구분을 두지 않아도 되지만 다양한 작업을 하기 위해서는 이러한 명령코드를 맨 앞에 위치시킵니다. 예를 들어서 POP3, FTP 등의 프로토콜도 이런 방식으로 메세지를 구분해주고 코드에 따라 처리를 다르게 해줍니다. "CHAT" 명령코드 뒤에는 메세지가 오도록 하였고 명령코드와 메세지간의 구분은 중간에 탭 값을 넣어주었습니다. chr(9)라는 함수를 이용해서 값을 추가했는데요 여기에서 ASCII 9번값이 TAB 값을 나타냅니다. 오래전에 배웠던 것 처럼 chr 함수는 ASCII 코드값을 이용해서 실질적인 캐리턱 코드로 변환을 해주는 함수죠. 그리고 메세지의 마지막 끝에 EndOfLine 캐릭터를 추가하여 메세지의 끝임을 나타내 줍니다. EndOfLine 값도 굉장히 중요한 값입니다. 이는 전체 보내지는 메세지의 구분을 해주기 위한 값이기 때문이지요. 이러한 값을 추가하지 않고 그냥 메세지를 보내게 되면 타이핑을 빠르게 입력 했을 때 앞뒤 메세지가 붙어서 전송되는 경우가 생길 수 있습니다. 그래서 반드시 메세지의 끝을 나타내주는 코드를 추가해줘야합니다. 여기에서 중요한 2가지는 소켓으로 메세지를 전송할 때에는 내용을 받는 Socket 쪽에서 메세지를 처리하기 위한 적절한 명령어를 사용한다는 것과 메세지의 끝을 알려주기 위한 코드를 추가한다는 점입니다.

마지막에 있는 ClientChatField.text = "" 는 메세지를 전송하고 나서 입력 필드의 내용을 다 지워주기 위한 간단한 코드입니다.

이제 ClientTCPSocket 을 통해서 메세지를 보냈습니다. 그럼 ServerTCPSocket 으로 메세지가 전송이 될 것이고 이것을 제대로 처리를 하여 메세지를 표현해주면 되겠죠? 그럼 ServerTCPSocket 콘트롤의 DataAvailable 이벤트를 선택하고 다음과 같은 코드를 작성합니다.

dim Temp, Message, Tag, ChatMessage, ConvertString as String
dim i, k, Count as Integer

Temp = me.ReadAll

Count = CountFields(Temp, EndOfLine)

for i=1 to Count
Message = NthField(Temp, EndOfLine, i)
Tag = NthField(Message, chr(9), 1)
Select case Tag
case "CHAT"
ChatMessage = NthField(Message, chr(9), 2)
ConvertString = ConvertEncoding(ServerMessageField.Text, Encodings.MacKorean)
ConvertString = ConvertString+ChatMessage+EndOfLine
ServerMessageField.Text = ConvertString
ServerMessageField.SelStart = lenb(ServerMessageField.text)*2

ServerMessageField.ScrollPosition =
ServerMessageField.LineNumAtCharPos(ServerMessageField.
CharPosAtLineNum(ServerMessageField.SelStart))

me.Write Message+EndOfLine
end select
next

위의 코드는 반복문과 조건문이 있어서 좀 복잡해 보일 수 있겠지만 굉장히 간단한 구성을 갖고 있습니다. 분석을 하자면 먼저 TCPSocket 함수 중 ReadAll 함수를 이용하여 Socket 의 버퍼에 들어온 모든 내용을 읽어들입니다. 그리고 EndOFLine 의 구분자를 이용해서 몇개의 메세지가 왔는지를 확인 한 다음 그 메세지 수에 따라 반복문을 돌려서 메세지를 처리하는 것입니다.

Temp = me.ReadAll

Count = CountFields(Temp, EndOfLine)

위의 코드가 버퍼의 내용을 읽어들이고 메세지의 숫자를 개산하는 코드입니다. 앞서 설명한 것처럼 EndOfLine 이 중요한 이유는 메세지를 받는 부분에서 EndOfLine 캐릭터를 이용해서 메세지를 구분하기 위함이지요. 이 갯수를 체크하기 위해서 CountFields 함수를 이용했습니다. CountField 함수는 해당 캐릭터 문자에 의해서 해당 문장에 몇개의 필드로 나누어지는지를 체크해주는 함수입니다. 여기에서 구한 Count 값을 이용해서 받은 메세지 만큼 반복문을 돌려서 각각의 메세지를 처리하게 됩니다. 그럼 for ~ next 반복문을 보도록 하겠습니다.

반복문의 첫줄을 보면 Message = NthField(Temp, EndOfLine, i) 코드가 있습니다. 이 코드가 바로 EndOfLine 을 체크하여 여러개의 메세지를 구분해서 문자형 변수인 Message 에 Socket 에서 받은 메세지를 대입하는 부분이 되죠. 이 때 사용한 함수는 NthField 함수입니다. Message 내용에는 "CHAT" 라는 명령어 코드와 ClientChatField 에서 입력한 메세지가 같이 들어가 있게 됩니다. 따라서 다음 Select case 조건문을 이용하여 앞 부분의 4개 코드의 명령코드를 확인 후 그에 따르는 메세지를 처리하게 되는 것이죠. 명령코드만을 확인하기 위해서 다시 NthField 함수를 이용하여 앞부분의 명령어 코드를 가져오게 됩니다.

Tag = NthField(Message, chr(9), 1)

여기에서 Chr(9) 라는 탭 값을 이용해서 명령코드를 가져왔죠. NthField(Message, chr(9), 2) 부분은 명령 코드가 제외된 실질적인 채팅 메세지 부분이 됩니다. 그리고 이 메세지를 분리해서 가져온 후에 문자코드를 다시 한번 변환을 해줍니다. 그리고 ServerMessageField 콘트롤의 Text 속성에 대입을 하게 되는 것이죠. 그리고 ServerMessageField 콘트롤의 Text 속성에 대입된 메세지를 화면에 표시가 되는 것 입니다. 여기에서 주의 할 점 중 하나는 메세지가 화면에 나타날 때의 스크롤 입니다. 보통 채팅창을 보면 기존 메세지는 위로 올라가고 새로운 메세지가 하단에 계속 나타나게 되어 쉽게 메세지를 볼 수 있는 인터페이스를 갖습니다. 이를 해주기 위해서 기존의 메세지를 다시 받은 후에 그 뒤에 계속 메세지를 붙이게 되는 것이죠. 위의 코드에서는 한글변환까지 해주기 위해서 ConvertString 이라는 변수를 이용해서 기존 메세지에 새로운 메세지를 추가했습니다.

ConvertString = ConvertEncoding(ServerMessageField.Text, Encodings.MacKorean)
ConvertString = ConvertString+ChatMessage+EndOfLine

하지만 위의 코드만 하면 메세지를 입력이 되지만 스크롤은 자동으로 되지 않습니다. 그래서 스크롤을 해주기 위한 편법 비슷한 팁을 사용했습니다.

ServerMessageField.ScrollPosition = ServerMessageField.LineNumAtCharPos
(ServerMessageField.CharPosAtLineNum(ServerMessageField.SelStart))

위의 코드는 메세지의 스크롤 포지션을 맨 밑으로 보내주는 편법 중 하나입니다. 이것은 필자가 생각한 편법중 하나인데요. 인전 버젼에서는 더 간단하게 되었었는데 5.x 대에서는 위와 같이 해주지 않으면 맨 밑으로 스크롤이 제대로 되지 않더군요. 여러분들도 다른 방법이 있다고 하면 그 방법을 사용해도 좋습니다. 프로그래밍 코드란 항상 절대적인 한가지만 있는 것은 아니기 때문이지요.

여튼 위의 코드 까지가 받은 메세지를 화면에 표현을 해주는 코드입니다. 그런데 맨 마지막 부분에 다음과 같은 코드가 있는 것을 발견할 수 있을 것 입니다.

me.Write Message+EndOfLine

위의 코드는 뭘까요? 바로 ServerTCPSocket 에 접속된 ClientTCPSocket 에 다시 받은 메세지를 보내는 것입니다. 그럼 왜 다시 똑같은 메세지를 보낼까요? 그것은 서버에서 메세지를 제대로 받았다는 것을 Client 에게 다시 알리는 방법이 되기 때문입니다. 또는 여러명이 접속해서 만들어지는 채팅 프로그램이나 메신저에서 접속된 유저에게 동시에 메세지를 보내기 위함이죠. 자신이 보냈다고 해서 자신의 메세지 필드에 직접 메세지를 표시하게 되면 서버의 접속이 끊어졌을 경우나 인터넷 라인에 문제가 생겼을 경우 다른 유저들에게는 메세지가 보이지 않을 수 있기 때문에 혼자 떠드는 경우가 생길 수도 있기 때문입니다. 이는 투명성(? 좀 말다운 말을 써봤습니다..^^;;) 에도 어긋나기 때문이지요. 따라서 자신이 보낸 메세지도 반드시 서버를 통해서 다시 받는 것이 제일 명확한 방법입니다. 이러한 규칙은 프로그램을 만들거나 다른 프로그램을 접하면서 익힐 수 있는 것이기 때문에 잘 알아두시기 바랍니다.

이제 ServerTCPSocket 의 DataAvailable 이벤트에 작성을 하여 ServerTCPSocket 데이타 처리 부분도 모두 완료를 했습니다. 이제는 ClientTCPSocket 의 DataAvailable 이벤트에 메세지 데이타를 처리하는 부분을 작성해야할 차례입니다. ClientTCPSocket 콘트롤도 ServerTCPSocket 콘트롤과 똑같이 메세지 데이타를 서버로 부터 받기 때문이지요. 따라서 이번에는 ClientTCPSocket 의 DataAvailable 이벤트에 다음과 같은 코드를 작성합니다.
dim Temp, Message, Tag, ChatMessage, ConvertString as String
dim i, k, Count as Integer

Temp = me.ReadAll

Count = CountFields(Temp, EndOfLine)

for i=1 to Count
Message = NthField(Temp, EndOfLine, i)
Tag = NthField(Message, chr(9), 1)
Select case Tag
case "CHAT"
ChatMessage = NthField(Message, chr(9), 2)
ConvertString = ConvertEncoding(ClientMessageField.Text, Encodings.MacKorean)
ConvertString = ConvertString+ChatMessage+EndOfLine
ClientMessageField.Text = ConvertString
ClientMessageField.SelStart = lenb(ClientMessageField.text)*2

ClientMessageField.ScrollPosition = ClientMessageField.LineNumAtCharPos
(ClientMessageField.CharPosAtLineNum(ClientMessageField.SelStart))
end select
next
위의 코드는 ServerTCPSocket 의 DataAvailable 에 작성된 코드와 거의 유사합니다. 하지만 조금 다른 점은 맨 마지막 부분에 작성되었던 me.Write Message+EndOfLine 코드가 없다는 점이죠. 그리고 메세지를 표현해주는 메세지 콘트롤이 ClientMessageField 라는 점도 다르구요. 만약에 이곳에도 Server 부분과 마찬가지로 me.Write Message+EndOfLine 코드가 작성되었다면 메세지를 한번 보내고 나면 계속해서 서로 자동으로 보내기 때문에 프로그램이 끝이 없이 동작을 할 것 입니다. 그래서 Client 부분에서는 메세지 데이타를 받기만 하도록 처리하면 됩니다. 이 부분을 위와 같이 처리하게 되면 서버에서 받은 메세지만 처리하는 것이 아니라 서버 쪽에서 직접 보낸 메세지도 처리할 수 있습니다. 따라서 서버에서도 메세지를 보내도록 ServerChatField 의 KeyDown 이벤트에 다음과 같은 코드를 작성하도록 합니다.
if key = chr(13) then
Message = ServerChatField.text

Temp = "CHAT"+chr(9)+Message+EndOfLine
Temp = ConvertEncoding(Temp, Encodings.MacKorean)
ServerTCPSocket.Write Temp
ServerChatField.text = ""

ConvertString = ConvertEncoding(ServerMessageField.Text, Encodings.MacKorean)
ConvertString = ConvertString+Message+EndOfLine
ServerMessageField.Text = ConvertString
ServerMessageField.SelStart = lenb(ServerMessageField.text)*2

ServerMessageField.ScrollPosition =
ServerMessageField.LineNumAtCharPos(ServerMessage
Field.CharPosAtLineNum(ServerMessageField.SelStart))
end if
예제에서는 서버에서도 데이타를 보이게 하기 위해서 위와 같이 서버쪽에서 데이타를 보낼 경우에는 ServerMessageField 에 직접 메세지를 보내도록 하였습니다. 그 외에는 ServerTCPSocket 콘트롤 함수의 Write 함수를 이용하여 ClientTCPSocket 에 데이타를 보내는 것이 앞서 했던 예제 부분과 똑같습니다.

이제 프로그램은 완성이 됐습니다. 네트웍 프로그래밍이 처음이신 분들은 생소하게 느껴지실 수도 있겠지만 생각보다는 간단하다는 것을 느끼셨을 것입니다. 그럼 완성된 프로그램을 실행해서 테스트를 해보시기 바랍니다.

- 프로그램의 완성
이제 Command + R 키를 눌러서 프로그램을 실행을 해봅니다. 프로그램이 실행되면 먼저 오른쪽에 있는 Server 부분에서 Listen 버튼을 눌러줍니다. 이 부분을 먼저 눌러줘야 ServerTCPSocket 이 Listen 함수를 실행하여 대기상태가 됩니다. 그러면서 Listen 버튼의 Caption 속성이 "Close" 로 바뀌는 것을 확인할 수 있을 것입니다. 왜냐하면 그렇게 만들었기 때문이지요..^^;; 그럼 이제 왼쪽 편의 Client 부분에서 Connect 버튼을 눌러줍니다. Address 와 Port 는 미리 나타나게 하였기 때문에 Connect 버튼만 눌러줘도 자신의 서버에 접속이 됩니다. 접속이 되면 Client 부분의 ConnectButton 콘트롤의 Caption 속성이 "Disconnect" 로 바뀔 것 입니다. 접속이 되면 그렇게 바뀌도록 앞서 코드를 작성했기 때문이지요. 그리고 Server 부분의 InfoText 콘트롤의 Text 속성도 "Connected" 로 바뀔 것입니다. 그럼 이제 신나게 양쪽의 ChatField 에서 메세지를 작성하고 리턴키를 눌러보시기 바랍니다. 양쪽 메세지 화면에 채팅 메세지가 나타나는 것을 확인할 수 있을 것입니다.

제대로 프로그램을 만든다는 것은 항상 힘이 듭니다. 위의 예제도 완전한 채팅 프로그램은 아니며 약간의 기능을 이용하여 채팅환경을 구현한 것입니다. 앞서 했었던 공부들을 제대로 이해하고 파악했다면 이를 이용해서 메신저나 채팅 프로그램으로 확장 할 수도 있을 것 입니다.

b. HTTPSocket 의 Get 함수 예제
그럼 앞서 언급한 것 처럼 HTTPSocket 의 Get 함수 예제를 해보도록 하겠습니다. 내용은 아주 간단하니 하나하나 따라하시면 쉽게 HTTPSocket 의 Get 함수에 대해서 이해할 수 있을 것입니다. 이 예제를 하고 나면 HTTPSocket 이 얼마나 쉽게 리얼베이직에서 구현이 되고 사용할 수 있는지를 알 수 있을 것입니다. 그럼 시작해 볼까요?

- 인터페이스 구성
우선 리얼베이직을 실행시킵니다. 그리고 프로젝트에 기본으로 구성이 되어있는 Window1 의 Name 속성을 속성윈도우에서 "HttpGetWindow" 라고 정해줍니다. 그 다음으로는 EditField 콘트롤을 툴바에서 드래그 하여 HttpGetWindow 의 왼쪽 상단에 위치시킵니다. 이 필드는 URL 을 입력하는 필드가 될 것입니다. 이 EditField 의 Name 속성은 속성윈도우에서 "URLField"로 지정합니다.

그리고 이번에는 PushButton 콘트롤을 툴바에서 드래그 하여 좀 전에 생성한 URLField 의 오른쪽 부분에 위치시킵니다. 그리고 생성된 PushButton1 콘트롤의 Name 속성을 속성윈도우에서 "GetButton"으로 지정합니다. 또한 Caption 속성을 속성윈도우에서 "Get" 으로 설정합니다.

이제는 새로운 EditField 콘트롤을 지금 생성한 콘트롤들 하단에 배치시킵니다. 이 필드에는 HTTPSocket 을 통해서 받는 HTML 코드들이 Text 속성에 들어가서 화면에 나타날 필드입니다. 이제 이 생성한 EditField 콘트롤의 Name 속성을 "ReceiveField" 로 정해줍니다. 또한 많은 텍스트 내용을 보여주기 위해서 MultiLine 속성을 True 로 설정합니다. 그리고 Font 부분은 한글서체로 지정합니다.
*필자는 Hangang 서체로 지정을 하였습니다.

이제 마지막으로 툴바에 위치한 TCPSocket 콘트롤을 HTTPGetWindow 내에 임의의 곳에 위치시킵니다. 이 TCPSocket 콘트롤의 Name 속성은 속성윈도우에서 "MyHttpSocket" 으로 설정합니다. 그리고 속성 윈도의 Super 속성의 오른쪽 화살표를 선택한 뒤에 HTTPSocket 클래스를 찾아서 Super 속성을 HTTPSocket으로 변경해 줍니다.

이제 인터페이스는 완성됐습니다. 다음 그림과 같이 배치시키면 될 것입니다.

- 코드 작성
이제 인터페이스가 완성이 되었으니 코드를 작성해 보도록 합니다. 우선 GetButton 을 더블클릭하여 코드 에디터를 활성화 시키고 Action 이벤트에 다음과 같은 코드를 작성합니다.
dim URL as String

URL = URLField.text

ReceiveField.text= ""

MyHTTPSocket.Get URL
위의 코드에 대해서 분석을 해보도록 하겠습니다. 위의 코드는 URL 이란 String 형의 변수를 이용하여 URLField 의 내용인 Text 속성을 가져오고 나서 MyHTTPSocket 의 Get 함수의 인수로서 사용하는 부분입니다. 중간에 ReceiveField.text = "" 코드는 HTML 코드를 가져올 때마다 ReceiveField 의 Text 속성을 모두 지워서 초기화 하기 위함입니다. 어떤 가요. 간단하죠?

위의 코드에서 알 수 있듯이 HTTPSocket 을 사용할 시에는 별도의 Connecet 나 포트 설정이 없이 URL 만을 이용한다는 점입니다. 포트는 앞서 말한것 처럼 80번으로 지정되어있고 접속은 Get 함수가 실행되면 자동으로 이루어집니다.

이제는 MyHTTPSocket 의 PageReceived 이벤트에 다음과 같은 코드를 작성합니다. PageReceived 이벤트에 코드를 작성하는 이유는 Get 함수를 통해서 데이타를 받아올 때에는 PageReceived 이벤트를 통해서 데이타를 가져올 수 있다는 점입니다.
dim temp as String

Temp = Content

ReceiveField.text = ReceiveField.Text+Temp
위의 코드도 아주 간단합니다. 앞서 배운 PageReceived 의 인수중 String 타입의 Content 인수를 이용하여 불려들여지는 HTML 데이타를 모두 ReceiveField 의 Text 속성에 입력을 하도록 작성되어져 있습니다. 이 곳에서는 받은 데이타를 단순히 ReceiveField 콘트롤에 입력만 했을 뿐입니다. 이것으로 끝입니다. 어떤가요? 너무 허무할 정도로 간단하다고요? 여튼 이제 프로그램을 실행해보도록 합니다.

- 프로그램의 실행
Command + R 키를 눌러서 디버깅 모드로 프로그램을 실행해 봅니다. 실행된 프로그램에서 첫번째 URLField에 "http://www.kissmac.com" 주소를 입력합니다. 그리고 GetButton 콘트롤을 눌러봅니다.
어떤가요? 잠시 기다리면 Kissmac.com 의 첫화면에 사용되는 HTML 소스들이 모두 ReceiveField 의 Text 속성에 들어와서 화면에 나타나는 것을 확인할 수 있을 것입니다.

kissmac.com의 첫화면 HTML 소스가 받아진 것을 확인할 수 있습니다.

위의 예제도 HTML 에 대해서 잘 알고 이해하는 유저분이 있고 지금까지의 리얼베이직 강좌를 잘 이해했다면 여러가지 용도로 확장하여 사용할 수 있을 것 입니다. 예를 들어서 필자는 이러한 기능을 이용해서 예전에 인터넷 영한 사전을 개발했었습니다. 여러분들이 더 많은 아이디어를 생각해서 이러한 예제를 기반으로 하여 더 좋은 프로그램을 만들 수 있는 기반이 되었으면 하네요..^^;;

이번 강좌의 예제는 여기 까지 입니다. 나머지 부분에 대해서는 위의 내용들을 기반으로 해서 한번식 참조해보시고 연습해 보시기 바랍니다.


간단하지만 리얼베이직의 네트웍 프로그래밍에 대해서 알아보았고 그 기반이 되는 Socket 에 대해서 알아보았습니다. 네트웍 프로그래밍은 예제를 보면서도 확인을 해서 알겠지만 그 자체로는 굉장히 어려운 기술을 쓰거나 하지는 않습니다. 대신 서로 데이타를 주고 받기 위한 규약의 정의라던지 관련 기능들을 같이 구현하는데 많은 코드들이 작성될 수 있으며 그에 따르는 규약에 대한 설계나 관리가 내용이 많아지면 어렵게 됩니다. 또한 디버깅 역시 쉽지는 않습니다. 하지만 네트웍 프로그래밍은 프로그래밍에 대해서 공부를 하는 여러분들에게 뭔가 새로운 세계를 열어줄 수 있는 부분중 하나라고 생각을 합니다. 왜냐하면 서로 다른 사람과의 커뮤니케이션을 통해 사용할 수 있는 소프트웨어는 사용자에게 새로운 즐거움을 주기 때문이지요. 그리고 모든 사람이 서로 공유할 수 있는 프로그램을 만들기 위해서는 반드시 이 네트웍이라는 부분이 포함되어야 합니다. 이번에 한 강좌는 내용은 많지 않지만 그런 가능성을 보여주기 위한 최소의 내용을 보여줬다고 생각을 합니다. 따라서 많은 분들인 많은 호기심과 재미를 갖고 이런 일에 시도를 해서 좋은 프로그램을 만들어 주셨으면 하는 바램도 생깁니다.



다음글 - 17회. Database -1-
현재글 - 16회. 리얼베이직의 기초 -14- 네트웍
이전글 - 15회. 리얼베이직의 기초 -13- 퀵타임 (2)