이 기사의 예에서는 Java가 마우스를 제어하여 화면 브로드캐스팅을 구현하는 방법을 설명합니다. 참고할 수 있도록 모든 사람과 공유하세요. 구체적인 분석은 다음과 같습니다.
이전 글 "Java에서 화면 공유 기능 구현 사례 분석"에서는 화면 캡처 시 마우스가 없다고 언급한 바 있는데, 교사 인터페이스에서 마우스를 보기 위해서는 각 스크린샷에 마우스를 그리면 됩니다. 다만, 스크린샷을 하나씩 찍다보니 보시는 마우스가 좀 걸리긴 합니다만, 예전에 자바 마우스 제어 애플릿을 작성했는데, 이런 식으로 마우스 데모를 보실 수 있습니다.
구현 방법도 매우 간단합니다. 이전 두 기사에서는 각각 마우스 없이 화면 공유 기능을 구현했습니다. 아래에서 간단히 분석해 보겠습니다.
서버 측에서 SendScreenImg 및 SendMouseMessage는 각각 서로 다른 포트를 수신하는 두 개의 도구 클래스로 간주되며 둘 다 Thread 클래스를 구현하고 스레드 풀 ExecutorService 클래스를 사용하여 이를 제어합니다.
마우스 정보와 그림 정보를 함께 보내는 방법을 아직 모르기 때문에 두 개의 포트가 사용됩니다. 어쩌면 그림을 바이트 배열로 변환하고 마우스 좌표를 배열 앞에 넣을 수도 있지만 이 경우에는 마우스 좌표 전송 속도가 사진 전송 속도보다 빠르기 때문에 일관성이 없을 수 있습니다. 시간이 있을 때 다시 시도해 보세요.
클라이언트 비유는 위와 동일합니다.
코드는 다음과 같습니다.
섬기는 사람:
주요 프로그램:
다음과 같이 코드 코드를 복사합니다:/*
* 화면 브로드캐스트 클래스는 스레드 풀을 사용하여 스크린샷 정보를 전송하는 클래스와 마우스 정보를 전송하는 클래스의 두 가지 도구 클래스를 호출합니다.
*/
공개 클래스 BroderCast {
공개 정적 무효 메인(문자열[] 인수)
{
새로운 BroderCast();
System.out.println("시작");
}
공개 BroderCast()
{
ExecutorService exector = Executors.newFixedThreadPool(2);
exector.execute(new SendScreenImg());
exector.execute(new SendMouseMessage());
}
}
스크린샷 코드 보내기:
다음과 같이 코드를 복사합니다. import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.DataOutputStream;
import java.io.IOException;
java.net.ServerSocket 가져오기;
java.net.Socket 가져오기;
java.util.zip.ZipEntry 가져오기;
java.util.zip.ZipOutputStream 가져오기;
javax.imageio.ImageIO 가져오기;
/*
* 도구: 교사 측에서 학생 측으로 스크린샷 정보를 보냅니다. 마우스 정보는 없으며 포트 8002가 사용됩니다.
* 전송된 그림의 구성요소에 마우스 정보를 그릴 수 있으므로, 학생 인터페이스에서 마우스 정보를 볼 수 있습니다. 이 기능은 아직 구현되지 않았습니다.
*
*/
공개 클래스 SendScreenImg는 스레드를 확장합니다.
{
공개 int serverPort=8002;
개인 ServerSocket serverSocket;
개인용 로봇 로봇;
공개 차원 화면;
공개 직사각형 직사각형;
개인 소켓 소켓;
공개 정적 무효 메인(문자열 인수[])
{
새로운 SendScreenImg().start();
}
공개 무효 변경ServerPort(int serverPort)
{
if(this.serverPort == serverPort) return;
노력하다{
this.serverSocket.close(); //현재 포트를 먼저 닫아야 합니다.
this.serverPort = 서버포트;
serverSocket = 새로운 ServerSocket(this.serverPort);
serverSocket.setSoTimeout(8000000);
}catch(예외 e){}
}
//소켓 연결 로봇을 오픈하고 화면 크기를 구하는 구성 방법
공개 SendScreenImg()
{
노력하다 {
serverSocket = new ServerSocket(getServerPort());
serverSocket.setSoTimeout(864000000);
로봇 = 새로운 로봇();
} 잡기(예외 e) {
e.printStackTrace();
}
screen = Toolkit.getDefaultToolkit().getScreenSize() //메인 화면의 크기를 가져옵니다.
ret = new Rectangle(screen); //해당 크기의 직사각형을 생성합니다.
}
@보수
공개 무효 실행()
{
//실시간으로 스크린샷 메시지 수신 대기
동안(참){
노력하다 {
소켓 = serverSocket.accept();
ZipOutputStream zip = new ZipOutputStream(new DataOutputStream(socket.getOutputStream()));
zip.setLevel(9); //압축 수준 설정
노력하다{
BufferedImage img = 로봇.createScreenCapture(직사각형);
zip.putNextEntry(new ZipEntry("test.jpg"));
ImageIO.write(img, "jpg", zip);
if(zip!=null)zip.close();
System.out.println("학생 포트가 연결되었습니다.");
} 잡기(IOException ioe) {
System.out.println("제어되는 터미널: 연결 해제");
}
} 잡기(IOException ioe) {
System.out.println("연결 오류");
} 마지막으로 {
if (소켓 != null) {
노력하다 {
소켓.닫기();
} 잡기(IOException e) {
}
}
}
}
}
}
마우스 정보 보내기:
다음과 같이 코드 코드를 복사합니다:/*
* 도구 클래스: 마우스 정보를 획득하여 학생 단말기로 전송
*/
공개 클래스 SendMouseMessage는 Thread를 확장합니다.
개인 int OPERATE_PORT = 8001;
개인 ServerSocket 서버;
개인 소켓 소켓;
개인 문자열 OperaStr;
공개 정적 무효 메인(문자열[] 인수)
{
새로운 SendMouseMessage().start();
}
공개 SendMouseMessage(){
노력하다 {
서버 = 새로운 ServerSocket(OPERATE_PORT);
//JOptionPane.showMessageDialog(null, "듣기를 시작했습니다.");
} 잡기(IOException e1) {
e1.printStackTrace();
}
}
//여러 스레드가 무선 루프에서 클라이언트를 모니터링합니다.
공개 무효 실행()
{
동안(참){
포인트 포인트 = MouseInfo.getPointerInfo().getLocation();
OperateStr = "Movemouse,"+point.x+","+point.y;
노력하다 {
소켓 = server.accept();
소켓.setSoTimeout(1000000);
DataOutputStream 출력 =new DataOutputStream(socket.getOutputStream());
output.write(operateStr.getBytes());
output.flush(); //출력 스트림을 플러시하고 버퍼링된 모든 출력 바이트를 씁니다.
output.close(); //출력 스트림을 닫고 리소스를 해제합니다.
System.out.println("INFO: "+operateStr);
} 잡기(IOException e) {
System.out.println("연결이 중지되었습니다.");
break; //연결을 끊을 때 무선 루프를 중지합니다.
}
}
}
}
고객:
주요 프로그램:
다음과 같이 코드를 복사합니다. import java.util.concurrent.ExecutorService;
java.util.concurrent.Executors 가져오기;
import com.Tool.OperateMouse;
import com.Tool.ReceiveImages;
공개 클래스 receiveBroderCast {
공개 ExecutorService 추출자;
공개 정적 문자열 IP="202.216.60.9";
공개 정적 무효 메인(문자열[] 인수)
{
새로운 receiveBroderCast(IP);
}
공개 ReceiverBroderCast(문자열 IP) {
exector = Executors.newFixedThreadPool(2);
exector.execute(새 수신이미지(IP));
exector.execute(new OperateMouse(IP));
}
}
스크린샷 코드 받기:
다음과 같이 코드 코드를 복사합니다:/*
* 2014-11-20
* 이 클래스는 마우스를 제외한 교사측으로부터 화면정보를 받기 위해 사용됩니다.
* 소켓() 사용
*/
공개 클래스 receiveImages는 스레드를 확장합니다{
공개 BorderInit 프레임;
공용 소켓 소켓;
공개 문자열 IP;
공개 정적 무효 메인(문자열[] 인수){
new receiveImages("202.216.60.7").start();
}
publicReceiveImages(문자열 IP)
{
프레임=새로운 BorderInit();
this.IP=IP;
}
공개 무효 실행() {
while(frame.getFlag()){
System.out.println("연결됨"+(System.currentTimeMillis()/1000)%24%60+"초");
노력하다 {
소켓 = 새 소켓(IP,8002);
DataInputStream ImgInput = new DataInputStream(socket.getInputStream());
ZipInputStream imgZip = new ZipInputStream(ImgInput);
이미지 img = null;
노력하다{
imgZip.getNextEntry(); //Zip 파일 스트림의 시작 부분으로 이동
img = ImageIO.read(imgZip); //Zip 이미지 스트림의 이미지를 바이트 단위로 읽습니다.
프레임.jlbImg.setIcon(new ImageIcon(img));
프레임.유효화();
}catch (IOException e) {e.printStackTrace();}
노력하다{
imgZip.close();
} 잡기(IOException e) {
System.out.println("연결이 끊어졌습니다.");
}
노력하다 {
TimeUnit.MILLISECONDS.sleep(50);//사진 수신 간격 시간
} 잡기(InterruptedException 즉) {
즉.printStackTrace();
}
} 잡기(IOException e) {
e.printStackTrace();
}마지막으로{
노력하다 {
소켓.닫기();
} 잡기(IOException e) {}
}
}
}
}
BorderInit 클래스는 JFrame을 확장합니다.
{
개인 정적 최종 긴 serialVersionUID = 1L;
공개 JLabel jlbImg;
개인 부울 플래그;
공개 부울 getFlag(){
this.flag를 반환합니다.
}
공개BorderInit()
{
this.flag=true;
this.jlbImg = 새로운 JLabel();
this.setTitle("원격 모니터링--IP:" + "--주제:" );
this.setSize(400, 400);
//this.setUndesignated(true);
//this.setAlwaysOnTop(true); //항상 위에 위치
this.add(jlbImg);
this.setLocationRelativeTo(null);
this.setExtendedState(Frame.MAXIMIZED_BOTH);
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
this.setVisible(true);
this.validate();
//창 닫기 이벤트
this.addWindowListener(new WindowAdapter() {
공공 무효 windowClosing(WindowEvent e) {
플래그=거짓;
BorderInit.this.dispose();
System.out.println("양식이 닫혔습니다.");
System.gc(); //가비지 수집
}
});
}
}
마우스 정보 수신 및 마우스 움직임 제어:
다음과 같이 코드를 복사합니다. import java.awt.AWTException;
import java.awt.Robot;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
java.net.Socket 가져오기;
import javax.swing.JOptionPane;
/*
* 학생 측의 마우스 제어는 교사 측의 마우스 제어와 동일합니다.
* 이 클래스는 robots.mouseMove() 함수를 사용하여 마우스 정보를 수신하고 마우스 움직임을 제어하는 역할을 담당합니다.
*/
공개 클래스 OperateMouse는 Thread를 확장합니다.
공개 정적 무효 메인(문자열[] 인수)
{
new OperateMouse("202.116.60.7").start();
}
개인 소켓 소켓;
공개 문자열 IP;
개인 int OPERATE_PORT = 8001;
개인용 로봇 로봇;
공개 OperateMouse(문자열 IP)
{
this.IP = IP;
}
공개 무효 실행() {
동안(참){
노력하다 {
소켓 = 새 소켓(IP,OPERATE_PORT);
로봇 = 새로운 로봇();
//마우스 움직임 정보 얻기
DataInputStream dataIn = new DataInputStream(socket.getInputStream());
문자열 정보="";
정수 r;
while((r=dataIn.read()) != -1){
info +=""+(char)r; //바이트 배열의 모든 요소를 문자 유형으로 변환합니다.
}
dataIn.close();
System.out.println("데이터 흐름 연결이 끊어졌습니다."+info);
if(정보!=null){
String s[] = info.trim().split(",");
if("Movemouse".equals(s[0].trim()));
{
if (s.길이 == 3) {
int x = Integer.parseInt(s[1].trim());
int y = Integer.parseInt(s[2].trim());
System.out.println("마우스 정보 출력"+x+" "+ y);
robots.mouseMove(x, y);
}
}
}
} 잡기(IOException e) {
System.out.println("연결이 끊어졌습니다");
부서지다;
} 잡기(AWTException e) {
e.printStackTrace();
}
}
}
}
이 글이 모든 사람의 Java 프로그래밍에 도움이 되기를 바랍니다.