일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 실습으로 다지는 c#
- 안드로이드 앱 개발
- 언제나휴일
- 졸업 작품 소재
- 실습
- 소스 코드
- 동영상 강의
- 동영상
- 원격 제어 프로그램
- 강의
- 산책하기 좋은 곳
- 충남 천안
- 유튜브 동영상 강의
- c언어
- 무료 동영상 강의
- Windows Forms
- 소켓 통신
- 언제나 휴일
- 네트워크 프로그래밍
- 클래스 다이어그램
- 표준 라이브러리 함수
- c#
- C++
- 알고리즘
- 캡슐화
- 파이썬
- 프로젝트
- 표준 입출력
- 추천
- 독립기념관
- Today
- Total
프로그래밍 언어 및 기술 [언제나휴일]
[C#] 원격 제어 프로그램 9. 원격 제어 – 화면 수신 서버 본문
1. 유튜브 동영상 강의
2. 원격 제어 – 화면 수신 서버
원격 제어 컨트롤러는 원격 제어 호스트의 화면을 주기적으로 수신하여 이를 보면서 제어합니다. 이제 원격 제어 화면을 수신하는 ImageServer 클래스를 구현합시다.
public class ImageServer
{
먼저 Listen 소켓과 연결 요청을 대기하고 수용하는 부분을 위한 스레드를 멤버로 선언합시다.
Socket lis_sock; //Listening 소켓
Thread accept_thread = null;
이미지를 수신할 때 이벤트 처리를 위해 RecvImageEventHandler 형식의 이벤트를 선언합시다.
public event RecvImageEventHandler RecvedImage = null;
생성자에서는 IP와 포트 정보를 받습니다.
public ImageServer(string ip, int port)
{
TCP 소켓을 생성하세요.
//소켓 생성
lis_sock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
소켓과 IP 단말 개체와 결합하고 백로그 큐를 설정합니다.
//EndPoint와 소켓 결합
IPAddress ipaddr = IPAddress.Parse(ip);
IPEndPoint ep = new IPEndPoint(ipaddr, port);
lis_sock.Bind(ep);
//Back 로그 큐 크기 설정
lis_sock.Listen(5);
클라이언트 연결 요청을 대기하고 수락하는 스레드를 생성하고 시작합니다.
//연결 수용 Loop을 수행하는 스레드 시작
ThreadStart ts = new ThreadStart(AcceptLoop);
accept_thread = new Thread(ts);
accept_thread.Start();
}
연결 요청을 대기하고 수락하는 AcceptLoop 메서드를 구현합시다.
void AcceptLoop()
{
try
{
클라이언트 연결 요청을 대기하고 수락하는 부분은 무한 반복합니다.
while (lis_sock != null)
{
Listen 소켓의 Accept 메서드를 호출하여 이미지를 수신할 작업 소켓을 구합니다.
Socket do_sock = lis_sock.Accept();//연결 수락
작업 소켓에서 이미지를 수신합니다.
Receive(do_sock);//do_sock으로 이미지 수신
}
}
catch
{
Close();
}
}
작업 소켓에서 이미지를 수신하는 Receive 메서드를 구현합시다.
void Receive(Socket dosock)
{
이미지 길이를 수신합니다.
byte[] lbuf = new byte[4]; //이미지 길이를 수신할 버퍼
dosock.Receive(lbuf); //이미지 길이 수신
수신한 이미지 길이만큼의 버퍼를 생성합니다.
int len = BitConverter.ToInt32(lbuf, 0);//수신한 버퍼의 내용을 정수로 변환
byte[] buffer = new byte[len];//이미지 길이만큼의 버퍼 생성
수신한 이미지 길이만큼의 이미지 데이터를 수신합니다.
int trans = 0;
while (trans < len)//수신할 이미지 데이터가 남아있으면
{
trans += dosock.Receive(buffer, trans,
len - trans,
SocketFlags.None);//이미지 수신
}
이미지 수신 이벤트에 등록 개체가 있으면 이미지 수신 이벤트를 발생합니다.
if (RecvedImage != null)//이미지 수신 이벤트가 존재하면
{
//이미지 수신 이벤트 발생
IPEndPoint iep = dosock.RemoteEndPoint as IPEndPoint;
수신한 버퍼를 이미지로 변환하여 이벤트 인자를 생성합니다.
RecvImageEventArgs e = new RecvImageEventArgs(iep, ConvertBitmap(buffer));
이미지를 수신한 이벤트를 발생합니다.
RecvedImage(this, e);
}
이미지를 수신하였으니 작업 소켓을 닫습니다.
dosock.Close();//소켓 닫기
}
수신한 이미지 버퍼를 이미지로 변환하는 ConvertBitmap 메서드를 구현합시다.
public Bitmap ConvertBitmap(byte[] data)
{
byte 배열을 이미지로 변환하기 위해 메모리 스트림 개체를 생성합니다.
MemoryStream ms = new MemoryStream();
메모리 스트림 개체에 수신한 이미지가 있는 버퍼의 내용을 기록합니다.
ms.Write(data, 0, (int)data.Length);//메모리 스트림에 버퍼를 기록
메모리 스트림 개체로 비트맵 개체를 생성하여 반환하세요.
Bitmap bitmap = new Bitmap(ms); //메모리 스트림으로 비트맵 개체 생성
return bitmap;
}
이미지 서버를 닫는 메서드도 제공합시다.
public void Close()
{
이미 닫혀있을 수도 있으니 존재할 때만 닫습니다.
if (lis_sock != null)
{
lis_sock.Close();
소켓을 닫았으면 다시 Close 메서드를 호출하여도 아무 작업을 하지 않게 null로 설정하세요.
lis_sock = null;
}
}
}
다음은 이번에 실습한 소스 코드입니다.
//ImageServer.cs
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.Drawing;
using System.IO;
using System;
namespace 원격제어기
{
/// <summary>
/// 이미지 수신 서버
/// </summary>
public class ImageServer
{
Socket lis_sock; //Listening 소켓
Thread accept_thread = null;
/// <summary>
/// 이미지 수신 이벤트
/// </summary>
public event RecvImageEventHandler RecvedImage = null;
/// <summary>
/// 생성자
/// </summary>
/// <param name="ip">로컬 IP</param>
/// <param name="port">포트</param>
public ImageServer(string ip, int port)
{
//소켓 생성
lis_sock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
//EndPoint와 소켓 결합
IPAddress ipaddr = IPAddress.Parse(ip);
IPEndPoint ep = new IPEndPoint(ipaddr, port);
lis_sock.Bind(ep);
//Back 로그 큐 크기 설정
lis_sock.Listen(5);
//연결 수용 Loop을 수행하는 스레드 시작
ThreadStart ts = new ThreadStart(AcceptLoop);
accept_thread = new Thread(ts);
accept_thread.Start();
}
void AcceptLoop()
{
try
{
while (lis_sock != null)
{
Socket do_sock = lis_sock.Accept();//연결 수락
Receive(do_sock);//do_sock으로 이미지 수신
}
}
catch
{
Close();
}
}
void Receive(Socket dosock)
{
byte[] lbuf = new byte[4]; //이미지 길이를 수신할 버퍼
dosock.Receive(lbuf); //이미지 길이 수신
int len = BitConverter.ToInt32(lbuf, 0);//수신한 버퍼의 내용을 정수로 변환
byte[] buffer = new byte[len];//이미지 길이만큼의 버퍼 생성
int trans = 0;
while (trans < len)//수신할 이미지 데이터가 남아있으면
{
trans += dosock.Receive(buffer, trans,
len - trans,
SocketFlags.None);//이미지 수신
}
if (RecvedImage != null)//이미지 수신 이벤트가 존재하면
{
//이미지 수신 이벤트 발생
IPEndPoint iep = dosock.RemoteEndPoint as IPEndPoint;
RecvImageEventArgs e = new RecvImageEventArgs(iep, ConvertBitmap(buffer));
RecvedImage(this, e);
}
dosock.Close();//소켓 닫기
}
/// <summary>
/// 수신한 버퍼를 비트맵 이미지로 변환 메서드
/// </summary>
/// <param name="data">수신한 버퍼</param>
/// <returns>비트맵 이미지</returns>
public Bitmap ConvertBitmap(byte[] data)
{
MemoryStream ms = new MemoryStream();
ms.Write(data, 0, (int)data.Length);//메모리 스트림에 버퍼를 기록
Bitmap bitmap = new Bitmap(ms); //메모리 스트림으로 비트맵 개체 생성
return bitmap;
}
/// <summary>
/// 비트맵 이미지 서버 닫기 메서드
/// </summary>
public void Close()
{
if (lis_sock != null)
{
lis_sock.Close();
lis_sock = null;
}
}
}
}
'프로젝트 > C# 원격제어 프로그램' 카테고리의 다른 글
[C#] 원격 제어 프로그램 5. 원격 제어 요청 수신 이벤트 (0) | 2024.01.08 |
---|---|
[C#] 원격 제어 프로그램 6. 원격 제어 요청 수신 서버 (0) | 2024.01.08 |
[C#] 원격 제어 프로그램 7. 원격 제어 – 화면 전송 (0) | 2024.01.08 |
[C#] 원격 제어 프로그램 8. 원격 제어 – 화면 수신 이벤트 (1) | 2024.01.08 |
[C#] 원격 제어 프로그램 10. 원격 제어 이벤트 전송 클라이언트 (1) | 2024.01.08 |
[C#] 원격 제어 프로그램 11. 원격 제어 이벤트 수신 버퍼 분석 (0) | 2024.01.08 |
[C#] 원격 제어 프로그램 12. 원격 제어 이벤트 수신 이벤트 (0) | 2024.01.08 |
[C#] 원격 제어 프로그램 13. 원격 제어 이벤트 수신 서버 (1) | 2024.01.08 |