다. 키보드, 마우스 이벤트 송수신

이번에는 제어하는 호스트의 키보드와 마우스 이벤트를 전송하고 제어당하는 호스트에서 이를 수신하는 부분을 구현합시다.

 

먼저 제어하는 호스트의 키보드와 마우스 이벤트를 전송하는 부분을 구현합시다. 먼저 프로젝트에 SendEventClient 클래스를 추가하세요.

 

전송하고 수신할 메시지 종류를 열거형으로 정의합시다.

상대측 IPEndPoint를 기억하는 멤버를 선언하세요.

생성자에서는 상대측 IP와 포트를 입력인자로 받아서 IPEndPoint 개체를 생성합니다.

키를 누른 메시지를 전송하는 메서드를 구현합시다.

먼저 전송할 메시지 종류를 버퍼에 기록합니다.

그리고 누를 키를 byte 배열에 설정합니다. 맨 앞의 원소는 메시지 종류이므로 인덱스 1에서 4바이트에 설정해야 합니다. int 형식의 값을 byte 배열로 변환하여 설정합니다.

이제 버퍼를 전송합니다. 버퍼를 전송하는 부분은 별도의 메서드 SendData를 정의합시다.

먼저 TCP 소켓을 생성하여 연결합니다.

입력 인자로 받은 버퍼를 전송하고 연결을 끊습니다.

 

 

키를 뗀 메시지를 전송하는 메서드도 정의합시다. 구현 방법은 SendKeyDown과 비슷합니다.

먼저 메시지 종류를 버퍼의 맨 앞에 설정합니다.

그리고 키를 버퍼에 추가하여 전송합니다.

마우스를 눌렀을 때의 메시지를 전송하는 메서드를 정의합시다.

버튼 종류에 따라 메시지 종류를 설정합니다.

그리고 data를 전송합니다.

마우스를 떼었을 때의 메시지를 전송하는 메서드를 정의합시다.

버튼 종류에 따라 메시지 종류를 설정한 후에 메시지를 전송합니다.

마우스 이동 메시지를 전송하는 메서드를 정의합시다.

메시지 종류를 설정하고 좌표를 추가한 후에 메시지를 전송합니다.

메시지를 수신하는 서버에서는 수신한 버퍼의 내용을 분석하는 부분이 필요합니다. 여기에서는 Meta 클래스를 정의하여 분석한 정보를 표현합시다.

수신한 메시지 종류를 속성으로 제공합시다.

누르거나 뗀 키를 속성으로 제공합시다.

현재 마우스 좌표를 속성으로 제공합시다.

생성자는 수신한 버퍼를 입력 인자로 받습니다.

버퍼의 맨 앞에는 메시지 종류가 있습니다.

메시지 종류에 따라 키에 관한 메시지와 마우스 이동에 관한 메시지를 분석합니다. 마우스를 누르거나 떼었을 때는 메시지 종류 외에 다른 부가적인 메시지가 없습니다.

마우스 이동일 때 현재 좌표를 분석하는 메서드를 정의합시다.

X 좌표는 버퍼 인덱스 1~4, Y 좌표는 버퍼 인덱스 5~8에 있습니다.

키보드를 누르거나 떼었을 때의 키를 분석하는 메서드를 정의합시다.

키는 버퍼 인덱스 1~4에 있습니다.

 

키보드와 마우스 이벤트 발생 메시지를 수신하였을 때 이를 통보하기 위해 이벤트 방식을 사용할 것입니다. 이를 위해 RecvMEEventArgs 클래스를 추가하세요.

수신한 메시지를 분석한 Meta 개체를 속성으로 제공합시다.

 

사용하기 쉽게 키와 좌표, 메시지 종류도 속성으로 제공합니다.

생성자에서는 분석한 Meta 개체를 입력 인자로 받아 속성을 설정합니다.

이벤트 형식에 사용할 대리자를 정의합시다.

 

 

이제 RecvEventServer 클래스를 정의합시다.

서버의 Listen 소켓을 멤버로 선언합니다.

메시지를 수신하였을 때 처리를 위해 이벤트를 멤버로 선언합니다.

클라이언트의 연결 요청과 수용을 위한 스레드를 멤버로 선언합시다.

생성자 메서드는 자신의 IP와 포트를 입력 인자로 받습니다.

입력 인자로 받은 정보로 IPEndPoint 개체를 생성하여 TCP 소켓을 생성, 네트워크 인터페이스와 결합 및 Back 로그 큐를 설정합니다.

클라이언트 연결 요청을 수용을 위한 스레드를 생성 및 가동합니다.

클라이언트 연결 요청 및 수용하는 메서드를 구현합시다. 메서드 내에서 메시지를 수신하는 부분을 비동기 처리를 위해 대리자를 정의할게요.

메시지를 수순하는 부분을 처리할 대리자 개체를 생성합니다.

클라이언트 연결 요청 및 수용하는 부분은 무한 반복합니다.

ListenSocket의 Accept 메서드를 호출합니다.

그리고 메시지를 수신하는 대리자를 수행합니다.

예외가 발생하면 Close 메서드를 호출하여 해제화합니다.

 

메시지를 수신하는 메서드를 구현합시다.

먼저 크기가 9인 버퍼를 생성하여 메시지를 수신합니다. 클라이언트 측에서는 전송할 메시지 종류에 관계없이 고정길이 버퍼에 데이터를 설정하여 보내게 구현하였습니다.

메시지 수신 이벤트 핸들러가 있으면 이벤트를 발생합니다.

소켓을 닫습니다.

메시지 수신 서버를 닫는 메서드를 제공합시다.

스레드와 Listen 소켓을 해제합니다.

 

[소스 9.7] SendEventClient.cs

 

[소스 9.8] Meta.cs

 

[소스 9.9] RecvKMEEventArgs.cs

 

[소스 9.10] RecvEventServer.cs