일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 소스 코드
- 산책하기 좋은 곳
- 알고리즘
- 표준 입출력
- 유튜브 동영상 강의
- 표준 라이브러리 함수
- 네트워크 프로그래밍
- 언제나휴일
- C++
- 언제나 휴일
- 프로젝트
- 실습으로 다지는 c#
- 소켓 통신
- 강의
- 추천
- 캡슐화
- c#
- c언어
- 파이썬
- 졸업 작품
- 원격 제어 프로그램
- Windows Forms
- 무료 동영상 강의
- 졸업 작품 소재
- 안드로이드 앱 개발
- 충남 천안
- 실습
- 동영상 강의
- 동영상
- 클래스 다이어그램
Archives
- Today
- Total
프로그래밍 언어 및 기술 [언제나휴일]
[C#] 원격 제어 프로그램 7. 원격 제어 – 화면 전송 본문
1. 유튜브 동영상 강의
2. 원격 제어 – 화면 전송
이번에는 원격 제어를 허용한 호스트의 전체 화면을 제어하는 컨트롤러에게 주기적으로 화면을 전송해야 합니다. 이 부분을 담당하는 ImageClient를 작성합시다.
public class ImageClient
{
전송에 사용할 소켓을 멤버 필드로 선언하세요.
Socket sock;
생성자에서는 이미지를 수신할 컨트롤러의 IP와 포트 번호를 입력 인자로 받습니다.
public ImageClient(string ip, int port)
{
소켓을 생성하세요.
//소켓 생성
sock = new Socket(AddressFamily.InterNetwork, //네트워크 주소 체계
SocketType.Stream,//전송 방식
ProtocolType.Tcp);//프로토콜
이미지를 수신할 컨트롤로와 연결합니다.
IPAddress ipaddr = IPAddress.Parse(ip);
IPEndPoint ep = new IPEndPoint(ipaddr, port);
sock.Connect(ep);//연결 요청
}
이미지를 전송하는 메서드를 정의합시다.
public bool SendImage(Image img)
{
if (sock == null) //소켓이 없을 때
{
return false;
}
이미지를 선형적으로 보내기 위해 메모리 스트림 개체를 생성합니다.
MemoryStream ms = new MemoryStream();//메모리 스트림 개체 생성
이미지 정보를 JPEG 포멧으로 스트림 개체에 저장합니다.
//이미지 정보를 JPEG 포멧으로 메모리 스트림에 저장
img.Save(ms, ImageFormat.Jpeg);
그리고 메모리 스트림에 이미지를 저장한 버퍼를 얻어옵니다.
//메모리 스티림의 버퍼를 가져오기
byte[] data = ms.GetBuffer();
try
{
int trans = 0;
소켓으로 전송할 이미지 버퍼의 길이를 byte 배열 개체로 만드세요.
//버퍼의 크기를 구하여 바이트 배열로 변환
byte[] lbuf = BitConverter.GetBytes(data.Length);
먼저 이미지 버퍼의 길이를 전송합니다.
sock.Send(lbuf);//버퍼 길이 전송
그리고 이미지를 전송합니다.
//전송한 크기가 데이터 길이보다 작으면 반복
while (trans < data.Length)
{
//버퍼 전송
trans += sock.Send(data, trans,
data.Length - trans,
SocketFlags.None);
}
전송이 끝나면 소켓을 닫습니다.
sock.Close();//소켓 닫기
sock = null;
return true;
}
catch
{
예외가 발생하면 응용을 끝내기로 할게요. 이 프로그램은 원격 제어 프로그램을 만드는 방법을 다루고 있으면 상품 수준으로 작성한 것은 아닙니다. 상품 수준으로 만들기 위해서는 다양한 조건으로 테스트를 수행하고 비정상적인 버그들을 잡는 과정이 필요합니다.
Application.Exit();//응용 끝내기
return false;
}
}
이미지를 보내는 부분은 비동기로 처리할 수 있게 합시다. 이를 위해 대리자를 정의할게요.
//비동기로 이미지를 보내는 메서드의 대리자
public delegate bool SendImageDele(Image img);
//이미지를 비동기로 전송 메서드
public void SendImageAsync(Image img, AsyncCallback callback)
{
대리자 개체를 생성하여 비동기로 수행할 수 있게 BeginInvoke 메서드를 호출하세요.
//비동기로 이미지 보내는 대리자 생성
SendImageDele dele = new SendImageDele(SendImage);
//비동기로 이미지 전송
dele.BeginInvoke(img, callback, this);
}
이미지 전송 클라이언트를 닫는 메서드도 제공합시다.
public void Close()
{
if (sock != null)
{
sock.Close();//소켓 닫기
sock = null;
}
}
}
다음은 이번 실습에서 작성한 소스 코드입니다.
//ImageClient.cs
using System;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.Drawing;
namespace 원격제어기
{
/// <summary>
/// 이미지 전송 클라이언트
/// </summary>
public class ImageClient
{
Socket sock;
/// <summary>
/// 생성자
/// </summary>
/// <param name="ip">컨트롤러의 IP 주소</param>
/// <param name="port">컨트롤러의 포트</param>
public ImageClient(string ip, int port)
{
//소켓 생성
sock = new Socket(AddressFamily.InterNetwork, //네트워크 주소 체계
SocketType.Stream,//전송 방식
ProtocolType.Tcp);//프로토콜
IPAddress ipaddr = IPAddress.Parse(ip);
IPEndPoint ep = new IPEndPoint(ipaddr, port);
sock.Connect(ep);//연결 요청
}
/// <summary>
/// 이미지 전송 메서드
/// </summary>
/// <param name="img">전송할 이미지</param>
/// <returns>전송 성공 여부</returns>
public bool SendImage(Image img)
{
if (sock == null) //소켓이 없을 때
{
return false;
}
MemoryStream ms = new MemoryStream();//메모리 스트림 개체 생성
img.Save(ms, ImageFormat.Jpeg);//이미지 개체를 JPEG 포멧으로 메모리 스트림에 저장
byte[] data = ms.GetBuffer();//메모리 스티림의 버퍼를 가져오기
try
{
int trans = 0;
byte[] lbuf = BitConverter.GetBytes(data.Length);//버퍼의 크기를 바이트 배열로 변환
sock.Send(lbuf);//버퍼 길이 전송
while (trans < data.Length)//전송한 크기가 데이터 길이보다 작으면 반복
{
trans += sock.Send(data, trans, data.Length - trans, SocketFlags.None);//버퍼 전송
}
sock.Close();//소켓 닫기
sock = null;
return true;
}
catch
{
Application.Exit();//응용 끝내기
return false;
}
}
/// <summary>
/// 비동기로 이미지를 보내는 메서드의 대리자
/// </summary>
/// <param name="img">전송할 이미지</param>
/// <returns>이미지 전송 성공 여부</returns>
public delegate bool SendImageDele(Image img);//비동기로 이미지를 보내는 메서드의 대리자
/// <summary>
/// 이미지를 비동기로 전송하는 메서드
/// </summary>
/// <param name="img">전송할 이미지</param>
/// <param name="callback">이미지 전송을 완료할 때 처리할 콜백</param>
public void SendImageAsync(Image img, AsyncCallback callback)//이미지를 비동기로 전송
{
SendImageDele dele = new SendImageDele(SendImage);//비동기로 이미지 보내는 대리자 생성
dele.BeginInvoke(img, callback, this);//비동기로 이미지 전송
}
/// <summary>
/// 이미지 클라이언트 닫기 메서드
/// </summary>
public void Close()
{
if (sock != null)
{
sock.Close();//소켓 닫기
sock = null;
}
}
}
}
'프로젝트 > C# 원격제어 프로그램' 카테고리의 다른 글
[C#] 원격 제어 프로그램 3. 프로젝트 생성 및 MainForm 자식 컨트롤 배치 (1) | 2024.01.08 |
---|---|
[C#] 원격 제어 프로그램 4. 원격 제어 요청 클라이언트 (0) | 2024.01.08 |
[C#] 원격 제어 프로그램 5. 원격 제어 요청 수신 이벤트 (0) | 2024.01.08 |
[C#] 원격 제어 프로그램 6. 원격 제어 요청 수신 서버 (0) | 2024.01.08 |
[C#] 원격 제어 프로그램 8. 원격 제어 – 화면 수신 이벤트 (1) | 2024.01.08 |
[C#] 원격 제어 프로그램 9. 원격 제어 – 화면 수신 서버 (0) | 2024.01.08 |
[C#] 원격 제어 프로그램 10. 원격 제어 이벤트 전송 클라이언트 (1) | 2024.01.08 |
[C#] 원격 제어 프로그램 11. 원격 제어 이벤트 수신 버퍼 분석 (0) | 2024.01.08 |