나. 제어 화면 송수신

이번에는 원격 제어를 허용한 호스트의 전체 화면을 제어하는 호스트에게 주기적으로 전송하고 수신하는 부분을 작성합시다.

 

먼저 이미지를 전송하는 ImageClient 클래스를 작성합시다.

전송에 사용할 소켓을 멤버 필드로 선언하세요.

 

생성자에서는 상대 IP와 포트 번호를 입력 인자로 받습니다.

입력 인자로 받은 정보로 IPEndPoint 개체를 생성합니다.

그리고 TCP 소켓을 생성하고 상대 호스트 EndPoint에 연결 요청합니다.

 

이미지를 전송하는 메서드를 정의합시다.

만약 소켓이 null이면 메서드를 종료합니다.

이미지를 선형적으로 보내기 위해 메모리 스트림 개체를 생성합니다.

이미지를 메모리 스트림에 저장합니다.

그리고 메모리 스트림에 이미지를 저장한 버퍼를 얻어옵니다.

소켓으로 전송할 이미지 버퍼의 길이를 byte 배열 개체로 만들어서 전송합니다.

그리고 이미지를 전송합니다.

전송이 끝나면 소켓을 닫습니다.

예외가 발생하면 응용을 끝냅니다.

비동기로 이미지를 전송하는 메서드도 제공합시다. 이 부분은 대리자를 이용할게요.

SendImage 메서드를 인자로 대리자를 생성하여 대리자를 비동기로 수행합니다.

이미지 전송 클라이언트를 닫는 메서드도 제공합시다.

 

이미지 수신 서버를 구현합시다. 이미지 수신 서버에서는 이미지를 수신할 때마다 폼에 이를 알려주어야 합니다. 이 부분을 위해 이벤트 처리를 할 것입니다. 먼저 이미지를 수신하였을 때 이벤트를 처리하기 위해 대리자와 이벤트 인자 클래스를 정의합시다. RecvImageEventArgs 이름의 클래스를 추가하세요.

이벤트 인자로 상대측 IPEndPoint를 가져오기 할 수 있는 속성을 제공합시다.

상대측 IP 주소 개체와 IP 주소 문자열과 포트 정보를 가져오기 할 수 있는 속성도 제공합시다.

이미지 개체와 이미지 크기에 관한 정보도 가져오기 할 수 있는 속성을 제공합시다.

생성자에서는 상대측 IPEndPoint 정보와 이미지 개체를 입력 인자로 받아 속성을 설정합니다.

ToString 메서드를 재정의하여 상대측 IP 정보와 이미지의 폭과 높이를 문자열로 형성하여 제공합시다.

이미지를 수신할 때 처리를 위한 대리자를 정의합시다.

 

이제 이미지 서버 클래스를 정의합시다.

먼저 Listen 소켓과 연결 요청을 대기하고 수용하는 부분을 위한 스레드를 멤버로 선언합시다.

이미지를 수신할 때 이벤트 처리를 위해 RecvImageEventHandler 형식의 이벤트를 선언합시다.

생성자에서는 IP와 포트 정보를 받습니다.

먼저 전달받은 정보로 IPEndPoint 개체를 생성합니다.

그리고 TCP 소켓을 생성하여 네트워크 인터페이스와 결합하고 백로그 큐를 설정합니다.

클라이언트 연결 요청을 대기하고 수락하는 스레드를 생성하고 시작합니다.

클라이언트 연결 요청을 대기하고 수락하는 부분은 무한 반복합니다.

Listen 소켓의 Accept 메서드를 호출합니다.

이미지를 수신합니다. 이 부분은 별도의 메서드로 정의합시다.

먼저 수신할 이미지 길이를 수신합니다.

그리고 이미지를 수신합니다.

만약 이미지 수신 이벤트 핸들러가 있으면 이벤트 인자를 생성하여 이벤트를 전송합니다. 이벤트 인자를 생성하기 위해 수신한 byte 배열을 이미지로 변환하는 부분은 별도의 메서드를 만들기로 합시다.

byte 배열을 이미지로 변환하기 위해 메모리 스트림 개체를 생성합니다.

메모리 스트림 개체에 수신한 이미지가 있는 버퍼의 내용을 기록합니다.

메모리 스트림 개체를 입력 인자로 Bitmap 개체를 생성하여 반환합니다.

이미지 서버를 닫는 메서드도 제공합시다.

스레드와 Listen 소켓을 해제하는 작업을 수행합니다.

 

[소스 9.4] ImageClient.cs

 

[소스 9.5] RecvImageEventArgs.cs

 

[소스 9.6] ImageServer.cs