본문 바로가기
Delphi Tip/통신

소켓 프로그래밍 기법의 활용 4편

by MonoSoft 2021. 12. 25.
728x90
반응형

소켓 프로그래밍 기법의 활용 4편



 


서버 소켓의 이용

 

어플리케이션을 TCP/IP 서버로 둔갑시키려면 

먼저 서버 소켓 컴포넌트인 TServerSocket 을 폼이나 데이터 모듈에 올려 놓는다. 

서버 소켓에서 제공하려는 서비스나 클라이언트의 요구를 기다릴 때 사용할 포트를 지정할 수 있다. 

각 서버 소켓 컴포넌트는 서버 윈도우 소켓 객체(TServerWinSocket)를 사용하여 

리스닝 연결에서의 서버측 종료점을 이루게 한다. 

 

또한, 서버가 받아들인 클라이언트 소켓과의 연결에서의 

서버 종료점에 대한 클라이언트 윈도우 소켓 객체(TServerClientWinSocket)도 활용한다.

 

● 포트의 지정

서버 소켓이 클라이언트의 요구를 기다리기 전에 (이런 기다림을 ‘listening’ 이라고 한다.) 서버가 

사용할 포트를 지정해 주어야 한다. 

이때 Port 프로퍼티를 사용해서 포트를 지정할 수 있다. 

서버 어플리케이션이 특정 포트 번호와 연관된 표준 서비스를 제공하는 경우라면 

Service 프로퍼티를 지정함으로써 간접적으로 포트를 지정할 수도 있다. 

만약에 Port와 Service 프로퍼티를 모두 지정한 경우라면 서버 소켓은 서비스 이름을 사용하게 된다.

 

● 클라이언트 요구 대기 (Listening for client request)

일단 서버 소켓 컴포넌트의 포트 번호를 설정하면, 

런타임에서 Open 메소드를 사용하여 리스닝 연결(listening connection)을 생성할 수 있게 된다. 

만약에 어플리케이션이 시작할 때 리스닝 연결을 자동으로 시작하게 하고 싶으면, 

디자인 시에 Active 프로퍼티를 True로 설정하면 된다.

 

● 클라이언트에 대한 연결 생성

리스닝 서버 소켓 컴포넌트는 클라이언트 연결 요구를 받는 족족 이를 허용한다. 

이렇게 되면 OnClientConnect 이벤트가 발생하며, 적절한 처리를 이벤트 핸들러에서 해주면 된다.

 

● 연결에 대한 정보 얻기​

일단 서버 소켓에서 리스닝 연결을 시작하면, 

서버 윈도우 소켓 객체를 사용해서 연결에 대한 정보를 얻을 수 있게 된다. 

서버 윈도우 소켓 객체는 Socket 프로퍼티를 이용해서 접근이 가능하다. 

이 윈도우 소켓 객체를 이용하면 서버 소켓 컴포넌트가 받아들인 클라이언트 소켓 객체들과의 

모든 활성화된 연결을 찾아낼 수 있으며, 

SocketHandle 프로퍼티를 이용해서 소켓 연결에 대한 핸들을 얻을 수도 있다. 

이 핸들을 사용해서 윈도우 소켓 API를 직접 호출할 수도 있다. 

또한, Handle 프로퍼티를 이용하면 소켓 연결에서 날아온 메시지를 받은 윈도우에 접근할 수 있다.

각각의 클라이언트 어플리케이션에 대한 활성화된 

연결은 서버 클라이언트 윈도우 소켓 객체(TServerClientWinSocket)에 캡슐화 되어 있다. 

이들 모두에게 접근할 때에는 서버 윈도우 소켓 객체의 Connections 프로퍼티를 이용하면 된다. 

서버 클라이언트 윈도우 소켓 객체에는 연결의 양쪽 종료점을 

형성하는 클라이언트와 소켓 객체에서 사용하는

포트 번호와 주소를 결정할 수 있는 프로퍼티가 있으며,

SocketHandle이라는 프로퍼티를 사용하면 윈도우 소켓 API 호출을 할 때 

사용할 수 있는 소켓 연결에 대한 핸들을 얻을 수도 있다. 

또한, Handle 프로퍼티를 사용하면 소켓 연결에서의 메시지를 받은 윈도우에 접근할 수 있으며, 

ASyncStyles 프로퍼티에서 메시지의 종류를 결정할 수도 있다.

 

● 연결의 종료​

리스닝 연결을 종료할 때에는 Close 메소드를 사용한다. 

이 메소드를 통해 클라이언트 어플리케이션과의 모든 연결을 단절시킬 수 있으며, 

리스닝 연결이 종료 되므로 서버 소켓은 더 이상 새로운 연결을 허용하지 않게 된다.

클라이언트가 서버 소켓과의 연결을 종료하면 OnClientDisconnect 이벤트가 발생하며, 

적절한 이벤트 핸들러를 이용해서 정리를 해준다.

 

소켓 이벤트

앞에서 몇 가지 이벤트에 대하여 이미 언급한 바가 있다. 

이를 간단히 먼저 정리하면 논-블로킹 연결이나 블로킹 연결에서 

소켓 연결에 대해 언제 데이터를 읽고, 쓸 것인지에 대한 이벤트가 있으며, 

서버 측에서 연결을 종료할 때 클라이언트 소켓에서 받게 되는 OnDisconnect 이벤트, 

그리고 클라이언트에서 연결을 종료할 때 서버 소켓에서 받게 되는 OnClientDisconnect 이벤트가 있다.

또한, 클라이언트와 서버 소켓 모두 연결에서 에러 메시지를 받게 되면 OnError 이벤트가 발생한다. 

그 밖에 연결을 열고, 완료할 때까지 여러가지 이벤트가 발생하게 된다.

 

● 클라이언트 이벤트​

클라이언트 소켓이 연결을 열게 되면, 다음과 같은 이벤트 들이 순차적으로 발생한다.

1. 서버 소켓을 찾기 전에 OnLookup 이벤트가 발생한다. 

     이 시점에서는 찾는 서버 소켓을 바꾸기 위해 Host, Address, Port, 

     Service 프로퍼티를 변경할 수 없다. Socket 프로퍼티를 이용해서 

     클라이언트 윈도우 소켓 객체에 접근할 수 있으며, 

     그 객체의 SocketHandle 프로퍼티를 이용해서 윈도우 API를 호출할 수 있다.

 

2. 윈도우 소켓이 설정되고, 초기화 된다.

3. 일단 서버 소켓을 찾으면 OnConnecting 이벤트가 발생한다. 

     이 시점에서는 윈도우 소켓 객체를 사용해서 서버 소켓에 대한 정보를 얻을 수 있게 

     되며, 연결에 사용되는 실제 포트와 IP 주소를 알 수 있다.

4. 연결 요구가 서버에 의해 받아들여지면 클라이언트 소켓에서 연결이 완료된다.

5. 연결이 완료되면 OnConnect 이벤트가 발생한다. 

     연결이 완료되는 즉시 데이터를 읽고, 쓰는 작업을 해야 할 때에는 

      OnConnect 이벤트 핸들러에 적절한 코드를 작성하면 된다.

 

● 서버 이벤트​

서버 소켓 컴포넌트는 리스닝 연결과 클라이언트 연결의 두가지 형태의 연결을 형성할 수 있다. 

이들 각각에 따라 발생하는 이벤트가 다르기 때문에, 따로 나누어 설명하겠다.

 

- 리스닝 연결 이벤트

 

리스닝 연결이 생성되기 직전에 OnListen 이벤트가 먼저 발생한다. 

이 시점에서 Socket 프로퍼티를 이용해서 서버 윈도우 소켓 객체에 접근할 수 있게 된다. 

이 객체의 SocketHandle 프로퍼티를 이용해서 연결이 생성되기 전에 

소켓에 대한 여러가지 사항을 바꾸어 볼 수가 있다. 

예를 들어, 서버가 리스닝에 사용하는 IP 주소를 제한하는 등의 처리를 할 수가 있다.

 

- 클라이언트 연결 이벤트

 

1. 연결의 서버측 종료점을 형성하는 소켓에 대한 윈도우 소켓 핸들을 넘겨주는 

     OnGetSocket 이벤트가 클라이언트 측에 소켓 객체를 넘겨줄 때 발생한다. 

     이때 개발자가 TServerClientWinSocket 클래스 대신에 

     자신만의 윈도우 소켓 객체를 대신 사용하도록 할 수 있다. 

     즉, OnGetSocket 이벤트 핸들러에서 자신의 윈도우 소켓 객체를 생성할 수 있다.

 

2. 이어서 OnAccept 이벤트가 발생하는데, 

     여기에는 새로운 TServerClientWinSocket 객체를 이벤트 핸들러에 넘겨 준다. 

     여기에서 처음으로     TServerClientWinSocket 객체를 이용해서 클라이언트에 

     연결된 서버측 종료점에 대한 정보를 이용할 수 있게 된다.

 

3. ServerType이 stThreadBlocking이면 OnGetThread 이벤트가 발생한다. 

     여기에서 자신만의 TServerClientThread 객체를 생성할 수 있으며, 이를 대신 사용하게 된다. 

     이어서 쓰레드가 실행되기 시작하면 OnThreadStart 이벤트가 발생한다. 

     쓰레드의 초기화나 쓰레드가 연결을 통해 데이터를 읽고, 

     쓰는 작업을 하려고 윈도우 소켓 API를 호출해야 한다면, 이 이벤트 핸들러에서 작업을 한다.

 

4. 클라이언트가 연결을 완료하면 OnClientConnect 이벤트가 발생한다. 

     논-블로킹 서버의 경우에는 이 시점에서 데이터를 읽고, 쓰기를 시작하면 된다.

 

 

5편 계속......

728x90
반응형

댓글