介绍

网络编程课上的实验,利用socket写的一个远程控制软件,能够实现对多个客户端基本的shell命令 cd mkdir touch rm(rd) copy,还能实现监控命令传回当前桌面截图,第一次被控制端连接时自动截图传回
;
服务器端:

import com.sun.xml.internal.org.jvnet.mimepull.CleanUpExecutorFactory;import java.awt.BorderLayout;import java.awt.Dimension;import java.awt.Toolkit;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyEvent;import java.awt.image.BufferedImage;
import java.io.*;import java.net.ServerSocket;import java.net.Socket;import java.nio.Buffer;
import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Scanner;import javax.swing.*;import javax.swing.border.TitledBorder;import static java.lang.Thread.sleep;public class ServerFrom extends JFrame{private int num_Image = 0 ;private JTextArea area;//在线的用户信息显示private DefaultListModel<String> dataModel;    //在线的用户列表显示private boolean isControl = true ;private   String contorl_name ;//注册的用户名不能相同//用于存储所有的用户,这里采用注册的"用户名"做key值,通信的socket做value值private Map<String, Socket> userMap=new HashMap<String, Socket>();public ServerFrom() {setTitle("聊天服务器");setDefaultCloseOperation(EXIT_ON_CLOSE);Toolkit toolkit=Toolkit.getDefaultToolkit();Dimension dim=toolkit.getScreenSize();int runWidth=500;int runHeight=400;int width=(int) dim.getWidth();int height=(int) dim.getHeight();//设置界面居中显示setBounds(width/2-runWidth/2, height/2-runHeight/2, runWidth, runHeight);area=new JTextArea();area.setEditable(false);getContentPane().add(new JScrollPane(area),BorderLayout.CENTER);//列表显示dataModel=new DefaultListModel<String>();JList<String> list=new JList<String>(dataModel);JScrollPane scroll=new JScrollPane(list);scroll.setBorder(new TitledBorder("在线"));scroll.setPreferredSize(new Dimension(100, this.getHeight()));getContentPane().add(scroll,BorderLayout.WEST);//菜单JMenuBar menuBar=new JMenuBar();setJMenuBar(menuBar);JMenu menu=new JMenu("控制(C)");menu.setMnemonic('C');    //设置快捷键为 Alt+CmenuBar.add(menu);//开启final JMenuItem itemRun=new JMenuItem("开启");//快捷键 Ctrl+RitemRun.setAccelerator(KeyStroke.getKeyStroke('R', KeyEvent.CTRL_MASK));itemRun.setActionCommand("run");menu.add(itemRun);//退出JMenuItem itemExit=new JMenuItem("退出");itemExit.setAccelerator(KeyStroke.getKeyStroke('E', KeyEvent.CTRL_MASK));itemExit.setActionCommand("exit");menu.add(itemExit);itemRun.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if("run".equals(e.getActionCommand())){startServer();itemRun.setEnabled(false);}}});setVisible(true);}private void startServer() {try {System.out.println("服务器启动");ServerSocket server=new ServerSocket(8090);area.append("启动服务器:"+server);//单独开启一个线程用于与客户端握手new ServerThread(server).start();new ClientThread_M().start();} catch (IOException e) {e.printStackTrace();}}class ServerThread extends Thread{private ServerSocket server;public ServerThread(ServerSocket server) {this.server=server;}@Overridepublic void run() {try {while(true) {if (isControl == true) {Socket s = server.accept();Scanner sc = new Scanner(s.getInputStream());if (sc.hasNext()) {String userName = sc.next();contorl_name = userName;area.append("\r\n" + userName + "控制端上线了。" + s);dataModel.addElement(userName + " 控制端");userMap.put(userName, s);}new ClientThread(s).start();isControl = false;}else {Socket s = server.accept();Scanner sc = new Scanner(s.getInputStream());InputStream in = s.getInputStream();if (sc.hasNext()) {String userName = sc.next();area.append("\r\n" + userName + "被控制端上线了。" + s);dataModel.addElement(userName);sendMsgToCon(userName);userMap.put(userName, s);}// new ClientThread(s).start();}}} catch (IOException e) {e.printStackTrace();}}}public void sendMsgToCon(String userName) throws IOException{Socket s=userMap.get(contorl_name);PrintWriter pw=new PrintWriter(s.getOutputStream(),true);//服务器向客户端发的消息格式设计://命令关键字@#发送方@#消息内容String msg="msg@#server@#"+userName+"登录了"; //用于显示用的.pw.println(msg);msg="cmdAdd@#server@#"+userName;   //用于给客户端维护在线用户列表用的pw.println(msg);//       pw.close();//       s.close();}class  ClientThread_M extends Thread{public  void  run() {while (true){for (Socket s : userMap.values()) {try {if (s.getInputStream().available() > 0) {Scanner sc = new Scanner(s.getInputStream());while (s.getInputStream().available() > 0) {String msg = sc.nextLine();area.append(msg + "\n");String msgs[] = msg.split("@#");//简单用户名处理(防黑)。//命令关键字@#接收方@#消息内容@#发送方if (msgs == null || msgs.length != 4) {System.out.println("通讯异常1:" + msg);return;}if ("send".equals(msgs[0])) {//表示客户端的请求是:向别人发送信息try {sendMsgToSb(msgs);} catch (InterruptedException e) {e.printStackTrace();}} else if ("exit".equals(msgs[0])) {//表示客户端发送的请求是:退出(下线)area.append("\r\n" + msgs[3] + "下线了" + s);dataModel.removeElement(msgs[3]);userMap.remove(msgs[3]);//通知其他所有在线的用户,***退出了// sendSbExitMsgToAll(msgs);sendSbExitMsgToCon(msgs);}//@#image@#发送者@#文件长度if ("image".equals(msgs[0])) {ImageToCon(msg);}}} else {continue;}} catch (IOException e) {e.printStackTrace();}}}}}class  ClientThread extends Thread{private  Socket con ;ClientThread(Socket s ){con = s ;}public  void  run() {while (true){try {if (con.getInputStream().available() > 0) {Scanner sc = new Scanner(con.getInputStream());while (sc.hasNext()){String msg = sc.nextLine() ;area.append(msg+"\n");String msgs[] = msg.split("@#");//简单用户名处理(防黑)。//命令关键字@#接收方@#消息内容@#发送方if (msgs == null || msgs.length != 4) {System.out.println("通讯异常1:" + msg);return;}if ("send".equals(msgs[0])) {//表示客户端的请求是:向别人发送信息try {sendMsgToSb(msgs);} catch (InterruptedException e) {e.printStackTrace();}} else if ("exit".equals(msgs[0])) {//表示客户端发送的请求是:退出(下线)area.append("\r\n" + msgs[3] + "下线了" + con);dataModel.removeElement(msgs[3]);userMap.remove(msgs[3]);//通知其他所有在线的用户,***退出了// sendSbExitMsgToAll(msgs);sendSbExitMsgToCon(msgs);}//@#image@#发送者@#文件长度if ("image".equals(msgs[0])){ImageToCon(msg);}}}else{continue;}} catch (IOException e) {e.printStackTrace();}}}}//命令关键字@#接收方@#消息内容@#发送方public void sendMsgToSb(String[] msgs) throws IOException, InterruptedException {命令关键字@#接收方@#消息内容@#发送方//msg@#消息发送者@#消息内容if("Controler".equals(msgs[1])){Socket s = userMap.get(contorl_name);String msg = "msg@#" + msgs[3] + "@#:\t" + msgs[2];PrintWriter pw = new PrintWriter(s.getOutputStream(), true);pw.println(msg);System.out.println(msg);}else {//发送给某一个人String userName=msgs[1];Socket s=userMap.get(userName);String msg = "msg@#" + msgs[3] + "@#操作命令: " + msgs[2];PrintWriter pw = new PrintWriter(s.getOutputStream(), true);pw.println(msg);//sleep(10);//在发给自己Socket s2 = userMap.get(contorl_name);PrintWriter pw2 = new PrintWriter(s2.getOutputStream(), true);String str2 = "msg@#" + "我" + "@#对 " + userName + "下达指令: " + msgs[2];pw2.println(str2);}}//通知其他所有在线的用户,***退出了//1) msg @# server @# 用户[userName]退出了  (给客户端显示用的)//2) cmdRed@#server @# userName (给客户端维护在线用户列表用的)public void sendSbExitMsgToCon(String[] msgs) throws IOException {Socket s=userMap.get(contorl_name);PrintWriter pw=new PrintWriter(s.getOutputStream(), true);String msg="msg@#server@#用户["+msgs[3]+"]退出了";pw.println(msg);msg="cmdRed@#server@#"+msgs[3];pw.println(msg);}public static void main(String[] args) {JFrame.setDefaultLookAndFeelDecorated(true);new ServerFrom();}
//"image@#Controler@#"+corrent+"@#"+userNamepublic void ImageToCon (String str) throws IOException {Socket s1=userMap.get(contorl_name);PrintWriter pw=new PrintWriter(s1.getOutputStream(), true);String msgs[] = str.split("@#");String msg="image@#"+msgs[3]+"@#"+msgs[2];int corrent = Integer.valueOf(msgs[2]);pw.println(msg);Socket  s = userMap.get(msgs[3]) ;BufferedOutputStream bos=new BufferedOutputStream(userMap.get(contorl_name).getOutputStream());InputStream in = s.getInputStream();FileOutputStream fos=new FileOutputStream("C:\\Users\\20218\\Desktop\\qq\\Image\\Sever\\"+msgs[3]+num_Image+".jpg");byte[] buf=new byte[corrent+1];int len= 0 ;int clen=0;System.out.println("corrent"+corrent);while((len=in.read(buf))!=-1) {System.out.println("len:"+len);fos.write(buf, 0, len);bos.write(buf, 0, len);clen +=len;if(clen>corrent||clen==corrent) {System.out.println("clen"+clen);break;}}num_Image++;}}

控制客户端:

import java.awt.BorderLayout;import java.awt.Color;import java.awt.Dimension;import java.awt.FlowLayout;import java.awt.Font;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.io.*;import java.net.Socket;import java.net.UnknownHostException;import java.util.Scanner;import javax.swing.*;import javax.swing.border.TitledBorder;public class ClientFrom extends JFrame implements ActionListener{private static String ip="127.0.0.1";private static int port=8090;private  int num_Image=0;private JTextField tfdUserName=new JTextField(10); //用户名作为唯一标识private JTextArea allMsg=new JTextArea();  //聊天信息显示private JTextField tfdMsg=new JTextField(10);//发送消息消息框private JButton btnSend;   //发送消息按钮private JButton btnCon;//在线用户列表private DefaultListModel<String> dataModel=new DefaultListModel<String>();private JList<String> list=new JList<String>(dataModel);public ClientFrom() {setBounds(600,300,600,400);addMenuBar();  //添加菜单上方面板/JPanel northPanel=new JPanel();//面板容器northPanel.add(new JLabel("用户名称"));tfdUserName.setText("");northPanel.add(tfdUserName);btnCon=new JButton("连接");btnCon.setActionCommand("connect");JButton btnExit=new JButton("退出");btnExit.setActionCommand("exit");northPanel.add(btnCon);northPanel.add(btnExit);getContentPane().add(northPanel,BorderLayout.NORTH);   //放在上方//中间面板JPanel centerPanel=new JPanel(new BorderLayout());//中allMsg=new JTextArea();allMsg.setEditable(false);allMsg.setForeground(Color.black);allMsg.setFont(new Font("宋体", Font.BOLD, 14));centerPanel.add(new JScrollPane(allMsg));//东list.setSelectedIndex(0);  //设置默认选择位置list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);   //设置只能单选list.setVisibleRowCount(5);       //设置显示的行数list.setFont(new Font("宋体", Font.BOLD, 12));JScrollPane scroll=new JScrollPane(list);     //为list添加滚动条scroll.setBorder(new TitledBorder("在线"));  //Border的实现类TitileBorderscroll.setPreferredSize(new Dimension(70, allMsg.getHeight()));    //设置滚动条的首选大小centerPanel.add(scroll,BorderLayout.EAST);//南JPanel southPanel=new JPanel();southPanel.add(new JLabel("消息"));southPanel.add(tfdMsg);btnSend=new JButton("发送");btnSend.setActionCommand("send");btnSend.setEnabled(false);southPanel.add(btnSend);centerPanel.add(southPanel,BorderLayout.SOUTH);//把中间面板加到框架中getContentPane().add(centerPanel);//事件监听btnCon.addActionListener(this);btnExit.addActionListener(this);btnSend.addActionListener(this);addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {if(tfdUserName.getText()==null || tfdUserName.getText().trim().length()==0){int result = JOptionPane.showConfirmDialog(ClientFrom.this, "你还没登录,是否退出");if(result==JOptionPane.YES_OPTION){System.exit(0);}else{return;}}System.out.println(tfdUserName.getText()+"退出");sendExitMsg();System.exit(0);}});setVisible(true);}private void addMenuBar() {JMenuBar menuBar=new JMenuBar();setJMenuBar(menuBar);JMenu menu=new JMenu("选项");menuBar.add(menu);JMenuItem itemSet=new JMenuItem("设置");itemSet.addActionListener(new ActionListener() {//对点击事件进行监听@Overridepublic void actionPerformed(ActionEvent e) {final JDialog setDlg=new JDialog(ClientFrom.this);setDlg.setBounds(ClientFrom.this.getX(), ClientFrom.this.getY(), 250, 100);setDlg.setLayout(new FlowLayout());setDlg.add(new JLabel("服务器:"));final JTextField tfdIP=new JTextField(10);tfdIP.setText(ip);setDlg.add(tfdIP);setDlg.add(new JLabel("端口:"));final JTextField tfdPort=new JTextField(10);tfdPort.setText(port+"");setDlg.add(tfdPort);JButton btnSet=new JButton("设置");btnSet.setActionCommand("set");JButton btnCanel=new JButton("取消");btnCanel.setActionCommand("canel");setDlg.add(btnSet);setDlg.add(btnCanel);btnSet.addActionListener(new ActionListener() {//对set按钮进行监听@Overridepublic void actionPerformed(ActionEvent e) {if("set".equals(e.getActionCommand())){if(tfdIP.getText()!=null && tfdIP.getText().trim().length()>0){ClientFrom.this.ip=tfdIP.getText();}if(tfdPort.getText()!=null && tfdPort.getText().trim().length()>0){try {ClientFrom.this.port=Integer.parseInt(tfdPort.getText());} catch (NumberFormatException e1) {JOptionPane.showMessageDialog(setDlg, "端口号格式输入错误,请输入数字");}}btnCon.setEnabled(true);tfdUserName.setEditable(true);if(client!=null){//如果前面已经登录着用户,就把用户退出String msg="exit@#全部@#null@#"+tfdUserName.getText();pw.println(msg);dataModel.clear();list.validate();//对表单进行认证(刷新)tfdUserName.setText("");}}else if("canel".equals(e.getActionCommand())){return;}}});setDlg.setVisible(true);}});menu.add(itemSet);}@Overridepublic void actionPerformed(ActionEvent e) {if("connect".equals(e.getActionCommand())){System.out.println(tfdUserName.getText());if(tfdUserName.getText()==null || tfdUserName.getText().trim().length()==0){JOptionPane.showMessageDialog(this, "用户名不能为空");return;}System.out.println(tfdUserName.getText()+":连接ing...");connecting();}else if("exit".equals(e.getActionCommand())){if(tfdUserName.getText()==null || tfdUserName.getText().trim().length()==0){int result = JOptionPane.showConfirmDialog(this, "你还没登录,是否退出");if(result==JOptionPane.YES_OPTION){System.exit(0);}else{return;}}System.out.println(tfdUserName.getText()+"退出");sendExitMsg();}else if("send".equals(e.getActionCommand())){if(tfdMsg.getText()==null){JOptionPane.showMessageDialog(this, "发送消息不能为空");return;}String msg="send@#"+list.getSelectedValue()+"@#"+tfdMsg.getText()+"@#"+tfdUserName.getText();pw.println(msg);System.out.println(msg);tfdMsg.setText("");}}private Socket client;private PrintWriter pw;private void connecting() {//与服务器建立连接,把userName传给服务器try {client=new Socket(ip,port);//发送用户名给服务器btnCon.setEnabled(false);  //连接成功后关掉连接按钮String userName=tfdUserName.getText().trim();pw=new PrintWriter(client.getOutputStream(),true);pw.println(userName);//连接之后,设置标题为userName在线setTitle(userName+"在线");btnSend.setEnabled(true);     //打开发送按钮tfdUserName.setEditable(false);       //用户名不能再修改//开一个线程单独用于跟服务器通信new ClientThread(client).start();} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}private void sendExitMsg() {//与服务器建立连接,把userName传给服务器try {client=new Socket(ip, port);String msg="exit@#全部@#null@#"+tfdUserName.getText();pw.println(msg);System.exit(0);} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}class ClientThread extends Thread{private Socket client;public ClientThread(Socket client) {this.client=client;}@Overridepublic void run() {//接收服务器返回的信息msg@#发送者@#小心内容try {Scanner sc=new Scanner(client.getInputStream());while(sc.hasNext()){String msg=sc.nextLine();String msgs[]=msg.split("@#");if(msgs==null || msgs.length!=3){System.out.println("通讯异常2");return;}if("msg".equals(msgs[0])){//表示该信息是用来显示用的if("server".equals(msgs[1])){//表示该信息是系统信息msg="系统信息:"+msgs[2];allMsg.append(msg+"\r\n");}else{//表示该信息聊天信息msg=msgs[1]+msgs[2];allMsg.append(msg+"\r\n");}}else if("cmdAdd".equals(msgs[0])){//表示该消息是用来更新用户在线列表的,添加用户dataModel.addElement(msgs[2]);}else if("cmdRed".equals(msgs[0])){//表示该消息是用来更新用户在线列表的,移除用户dataModel.removeElement(msgs[2]);}list.validate();   //需要刷新list,不然可能出现list更新失败的bugif("image".equals(msgs[0])){allMsg.append("收到来自于"+msgs[1]+"的截图\n");InputStream in = client.getInputStream();FileOutputStream fos=new FileOutputStream("C:\\Users\\20218\\Desktop\\qq\\Image\\Control\\"+msgs[1]+num_Image+".jpg");int corrent = Integer.valueOf(msgs[2]);byte[] buf=new byte[corrent];int len= 0 ;int clen=0;while((len=in.read(buf))!=-1) {System.out.println("len:"+len);fos.write(buf, 0, len);clen +=len;if(clen>corrent||clen==corrent) {System.out.println("clen"+clen);break;}}JFrame.setDefaultLookAndFeelDecorated(true);new ImageForm("C:\\Users\\20218\\Desktop\\qq\\Image\\Control\\"+msgs[1]+num_Image+".jpg");//JOptionPane.showConfirmDialog(null," ", "提示框", 2);num_Image++;}}} catch (IOException e) {e.printStackTrace();}}}public static void main(String[] args) {JFrame.setDefaultLookAndFeelDecorated(true);new ClientFrom();}}

被控制端:

import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.awt.image.BufferedImage;
import java.io.*;import java.net.Socket;import java.net.UnknownHostException;import java.util.Scanner;import javax.imageio.ImageIO;
import javax.swing.DefaultListModel;import javax.swing.JButton;import javax.swing.JDialog;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JList;import javax.swing.JMenu;import javax.swing.JMenuBar;import javax.swing.JMenuItem;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextArea;import javax.swing.JTextField;import javax.swing.ListSelectionModel;import javax.swing.border.TitledBorder;import static java.lang.Thread.sleep;public class ClientbcFrom extends JFrame implements ActionListener{private static String ip="127.0.0.1";private static int port=8090;private int num_image = 0 ;private String  m_dir =new String ("C:/Users/20218/Desktop/qq/");private JTextField tfdUserName=new JTextField(10); //用户名作为唯一标识private JTextArea allMsg=new JTextArea();  //聊天信息显示private JTextField tfdMsg=new JTextField(10);//发送消息消息框private JButton btnSend;   //发送消息按钮private JButton btnCon;//在线用户列表private DefaultListModel<String> dataModel=new DefaultListModel<String>();private JList<String> list=new JList<String>(dataModel);public ClientbcFrom() {setBounds(300,300,600,400);addMenuBar();  //添加菜单上方面板/JPanel northPanel=new JPanel();//面板容器northPanel.add(new JLabel("用户名称"));tfdUserName.setText("");northPanel.add(tfdUserName);btnCon=new JButton("连接");btnCon.setActionCommand("connect");JButton btnExit=new JButton("退出");btnExit.setActionCommand("exit");northPanel.add(btnCon);northPanel.add(btnExit);getContentPane().add(northPanel,BorderLayout.NORTH);   //放在上方//中间面板JPanel centerPanel=new JPanel(new BorderLayout());//中allMsg=new JTextArea();allMsg.setEditable(false);allMsg.setForeground(Color.black);allMsg.setFont(new Font("宋体", Font.BOLD, 14));centerPanel.add(new JScrollPane(allMsg));//南JPanel southPanel=new JPanel();centerPanel.add(southPanel,BorderLayout.SOUTH);//把中间面板加到框架中getContentPane().add(centerPanel);//事件监听btnCon.addActionListener(this);btnExit.addActionListener(this);allMsg.append("此为被控制端,控制端传输命令为:");//        btnSend.addActionListener(this);addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {if(tfdUserName.getText()==null || tfdUserName.getText().trim().length()==0){int result = JOptionPane.showConfirmDialog(ClientbcFrom.this, "你还没登录,是否退出");if(result==JOptionPane.YES_OPTION){System.exit(0);}else{return;}}System.out.println(tfdUserName.getText()+"退出");sendExitMsg();System.exit(0);}});setVisible(true);}private void addMenuBar() {JMenuBar menuBar=new JMenuBar();setJMenuBar(menuBar);JMenu menu=new JMenu("选项");menuBar.add(menu);JMenuItem itemSet=new JMenuItem("设置");itemSet.addActionListener(new ActionListener() {//对点击事件进行监听@Overridepublic void actionPerformed(ActionEvent e) {final JDialog setDlg=new JDialog(ClientbcFrom.this);setDlg.setBounds(ClientbcFrom.this.getX(), ClientbcFrom.this.getY(), 250, 100);setDlg.setLayout(new FlowLayout());setDlg.add(new JLabel("服务器:"));final JTextField tfdIP=new JTextField(10);tfdIP.setText(ip);setDlg.add(tfdIP);setDlg.add(new JLabel("端口:"));final JTextField tfdPort=new JTextField(10);tfdPort.setText(port+"");setDlg.add(tfdPort);JButton btnSet=new JButton("设置");btnSet.setActionCommand("set");JButton btnCanel=new JButton("取消");btnCanel.setActionCommand("canel");setDlg.add(btnSet);setDlg.add(btnCanel);btnSet.addActionListener(new ActionListener() {//对set按钮进行监听@Overridepublic void actionPerformed(ActionEvent e) {if("set".equals(e.getActionCommand())){if(tfdIP.getText()!=null && tfdIP.getText().trim().length()>0){ClientbcFrom.this.ip=tfdIP.getText();}if(tfdPort.getText()!=null && tfdPort.getText().trim().length()>0){try {ClientbcFrom.this.port=Integer.parseInt(tfdPort.getText());} catch (NumberFormatException e1) {JOptionPane.showMessageDialog(setDlg, "端口号格式输入错误,请输入数字");}}btnCon.setEnabled(true);tfdUserName.setEditable(true);if(client!=null){//如果前面已经登录着用户,就把用户退出String msg="exit@#Controler@#null@#"+tfdUserName.getText();pw.println(msg);tfdUserName.setText("");}}else if("canel".equals(e.getActionCommand())){return;}}});setDlg.setVisible(true);}});menu.add(itemSet);}@Overridepublic void actionPerformed(ActionEvent e) {if("connect".equals(e.getActionCommand())){System.out.println(tfdUserName.getText());if(tfdUserName.getText()==null || tfdUserName.getText().trim().length()==0){JOptionPane.showMessageDialog(this, "用户名不能为空");return;}System.out.println(tfdUserName.getText()+":连接ing...");try {connecting();} catch (AWTException e1) {e1.printStackTrace();}}else if("exit".equals(e.getActionCommand())){if(tfdUserName.getText()==null || tfdUserName.getText().trim().length()==0){int result = JOptionPane.showConfirmDialog(this, "你还没登录,是否退出");if(result==JOptionPane.YES_OPTION){System.exit(0);}else{return;}}System.out.println(tfdUserName.getText()+"退出");sendExitMsg();}}private Socket client;private PrintWriter pw;private void connecting() throws AWTException {//与服务器建立连接,把userName传给服务器try {client=new Socket(ip,port);//发送用户名给服务器btnCon.setEnabled(false);  //连接成功后关掉连接按钮String userName=tfdUserName.getText().trim();pw=new PrintWriter(client.getOutputStream(),true);pw.println(userName);//连接之后,设置标题为userName在线setTitle(userName+"在线");//截图功能的实现m_Imgae(userName);allMsg.append(userName+"传输图片完成\n");tfdUserName.setEditable(false);       //用户名不能再修改//开一个线程单独用于跟服务器通信new ClientThread(client).start();} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}}private void sendExitMsg() {//与服务器建立连接,把userName传给服务器//client=new Socket(ip, port);String msg="exit@#Controler@#null@#"+tfdUserName.getText();pw.println(msg);System.exit(0);}class ClientThread extends Thread{private Socket client;public ClientThread(Socket client) {this.client=client;}@Overridepublic void run() {//接收服务器返回的信息try {Scanner sc=new Scanner(client.getInputStream());while(sc.hasNext()){String msg=sc.nextLine();String msgs[]=msg.split("@#");if(msgs==null || msgs.length!=3){System.out.println("通讯异常");return;}if("msg".equals(msgs[0])){//表示该信息是用来显示用的if("server".equals(msgs[1])){//表示该信息是系统信息msg="系统信息:"+msgs[2];allMsg.append(msg+"\r\n");}else{//表示该信息聊天信息msg=msgs[1]+msgs[2];allMsg.append(msg+"\r\n");String options[] = msgs[2].split(" ");allMsg.append(options[1]+"\n");if("image".equals(options[1] )){try {//发送消息格式 image@#Controler@#文件长度@#发送者try {m_Imgae(tfdUserName.getText());} catch (InterruptedException e) {e.printStackTrace();}allMsg.append(tfdUserName.getText()+"传输图片完成\n");} catch (AWTException e) {e.printStackTrace();}}// dir@#Controler@#nullif("dir".equals(options[1])){allMsg.append("dir开始\n");m_dir();}if ("cd".equals(options[1])){allMsg.append("cd 开始");m_cd(options[2]);}if("cat".equals(options[1])){allMsg.append("cat开始");m_cat(options[2]);}if("rd".equals(options[1])){allMsg.append("rd 开始 \n");m_rd(m_dir+"/"+options[2]);}if("mkdir".equals(options[1])){allMsg.append("mkdir 开始\n");m_mkdir(m_dir+"/"+options[2]);}if("touch".equals(options[1])){allMsg.append("touch 开始\n");m_touch(options[2]);}if("copy".equals(options[1])){allMsg.append("copy 开始\n");m_copy(msgs[2]);}}}}} catch (IOException e) {e.printStackTrace();}}}public  void  m_Imgae(String userName) throws AWTException, IOException, InterruptedException {Robot robot=new Robot();BufferedImage bi=robot.createScreenCapture(new Rectangle(1500,800));ImageIO.write(bi, "jpg", new File("C:\\Users\\20218\\Desktop\\qq\\Image\\Client\\"+userName+num_image+".jpg"));allMsg.append("截图完成!\n");//图片传输FileInputStream fis = new FileInputStream("Image\\Client\\"+userName+num_image+".jpg");int corrent = 0 ;int len = 0;BufferedOutputStream bos=new BufferedOutputStream(client.getOutputStream());byte[] buf = new byte[1024*1024*5];byte[] temp1 = new byte[1024*1024*10];while((len=fis.read(buf))!=-1){corrent+=len;}pw.println("image@#Controler@#"+corrent+"@#"+userName);//获取输出流//OutputStream out = s.getOutputStream();//2.往输出流里面投放数据fis = new FileInputStream("Image\\Client\\"+userName+num_image+".jpg");// FileOutputStream fos=new FileOutputStream("C:\\Users\\20218\\Desktop\\qq\\Image\\Sever\\"+userName+num_image+1+".jpg");int length=0;System.out.println(fis.available());while((length=fis.read(temp1))!=-1){bos.write(temp1,0,length);System.out.println(length);//    fos.write(temp1,0,length);bos.flush();}// bos.write(buf,0,fis.available());// fos.write(temp1,0,fis.available());//fos.flush();num_image++;}// 接收消息格式 dir@#Controler@#null//发送消息格式 send@#Controler@#目录信息@#usernamepublic void m_dir() {String userName = tfdUserName.getText();File dirFile = new File(m_dir);//判断该文件或目录是否存在,不存在时在控制台输出提醒if (!dirFile.exists()) {System.out.println("do not exit\n");pw.println("send@#Controler@#该目录不存在@#" + userName);m_cd("..");return;}if (!dirFile.isDirectory()) {System.out.println("not a directory \n");pw.println("send@#Controler@# not a directory @#" + userName);return;}String[] fileList = dirFile.list();String msg = new String("send@#Controler@#");for (int i = 0; i < fileList.length; i++){File file = new File(dirFile.getPath(),fileList[i]);if(file.isDirectory()){msg+="文件夹:"+file.getName()+" ";}if (file.isFile()){msg+="文件: "+file.getName()+" ";}}msg+="@#";msg+=userName;allMsg.append(msg);pw.println(msg);allMsg.append("dir结束\n");}public void m_cd(String str){if("..".equals(str)) {String m_dirs[] =m_dir.split("/" );m_dir = new String("");for(int i =0 ;i<m_dirs.length-1;i++){if(i!=0)m_dirs[i]="/"+m_dirs[i];m_dir+=m_dirs[i];}}else{m_dir+="/";m_dir+=str;if(new File(m_dir).exists()){pw.println("send@#Controler@# 成功切换目录 当前目录为"+m_dir+" @#" + tfdUserName.getText());}else{m_cd("..");pw.println("send@#Controler@# 要切换的目录不存在 @#" + tfdUserName.getText());}}}public void m_cat(String str){if(new File(m_dir+"/"+str).exists()){pw.println("send@#Controler@# 成功执行指令正在打开图片 @#" + tfdUserName.getText());}else{pw.println("send@#Controler@# 该图片不存在 @#" + tfdUserName.getText());return;}JFrame.setDefaultLookAndFeelDecorated(true);new ImageForm(m_dir+"/"+str);}public void m_mkdir(String str){File file = new File(str);if( file.mkdirs())pw.println("send@#Controler@# 创建目录成功 @#" + tfdUserName.getText());elsepw.println("send@#Controler@# 创建目录失败 @#" + tfdUserName.getText());}public void m_touch(String str) throws IOException {File file = new File(m_dir+"/"+str);if( file.createNewFile())pw.println("send@#Controler@# 创建文件成功 @#" + tfdUserName.getText());elsepw.println("send@#Controler@# 创建文件失败 @#" + tfdUserName.getText());}public void m_copy (String str) throws IOException {String msgs[] = str.split(" ");if(msgs.length<4) {pw.println("send@#Controler@# 指令格式错误 @#" + tfdUserName.getText());return;}for(int i = 3;i<msgs.length;i++) {m_copy_f(m_dir+"/"+msgs[2],msgs[i]);pw.println("send@#Controler@# "+ msgs[i]+"复制成功 @#" + tfdUserName.getText());}}public void m_copy_f(String from , String to  ) throws IOException {File file = new File(from) ;if(!file.isDirectory()) {FileInputStream fis = new FileInputStream(from);FileOutputStream fos = new FileOutputStream(to);int length = 0;byte[] buf = new byte[1024 * 1024];while ((length = fis.read(buf)) != -1) {fos.write(buf, 0, length);}pw.println("send@#Controler@# "+ to+"复制成功 @#" + tfdUserName.getText());}else{if (!new File(to).exists()) {m_mkdir(to);}if(file.list().length ==0){return;}else {File list[] = file.listFiles();for (int i = 0 ;i<list.length;i++ ){allMsg.append(list[i].getPath()+"\n");m_copy_f(list[i].getPath(),to+"/"+list[i].getName());}}}}public void m_rd(String str){File file = new File(str);if (file.isDirectory()){if(file.list().length == 0){if(file.delete())allMsg.append("目录  "+file.getName()+"be deleted\n");}else {File list[] = file.listFiles();for (int i = 0 ;i<list.length;i++ ){allMsg.append(list[i].getPath()+"\n");m_rd(list[i].getPath());}}m_rd(file.getPath());}else {if (file.delete())allMsg.append("文件:" + file.getName() + " be  deleted \n");}}public static void main(String[] args) {JFrame.setDefaultLookAndFeelDecorated(true);new ClientbcFrom();}}

图片显示界面:

import javax.swing.*;public  class  ImageForm extends JFrame {ImageForm(String path){setBounds(100,100,1000,600);JPanel centerPanel  = new JPanel();JLabel label = new JLabel();label.setIcon(new ImageIcon(path));//文件路径centerPanel.add(label);getContentPane().add(centerPanel);setVisible(true);}}

讲解

本实验采用客户机服务器模式,拥有两种客户端:控制端与被控制端。服务器负责消息的传输。消息格式都在注释中。通过接受的消息来实现相应的功能,复制和截图采用的文件流,进行文件传输,有需要的可以改成定时截图从而实现实时监控。

演示

先打开服务器 然后登录控制端 最后登录被控制端。

java 实现可视化远程控制相关推荐

  1. java数据可视化平台初步构想

    2019独角兽企业重金招聘Python工程师标准>>> java数据可视化平台初步构想 平台架构 权限系统-负责后台用户权限 后台管理系统(oss)-负责后台运营配置相关操作 前端展 ...

  2. Java实现可视化迷宫

    代码地址如下: http://www.demodashi.com/demo/14547.html 需求 使用深度优先算法求解迷宫路径,使用Java实现求解过程的可视化,可单步运行,形象直观. 演示效果 ...

  3. Java+Swing可视化图像处理软件

    Java+Swing可视化图像处理软件 一.系统介绍 二.功能展示 1.图片裁剪 2.图片缩放 3.图片旋转 4.图像灰度处理 5.图像变形 6.图像扭曲 7.图像移动 三.系统实现 1.ImageP ...

  4. 一款基于 Java 的可视化 HTTP API 接口开发神器

    今天推荐的 5 个项目是: magic-api :一款基于 Java 的可视化 HTTP API 接口开发神器. LanguageTool : 一款基于 Java 语言编写的开源语言校正工具. toB ...

  5. 利用java实现可视化界面肯德基(KFC)点餐系统

    一.题目 使用java实现可视化KFC点餐系统. 二.题目分析 根据java中的用户图形界面包中的各个类设计界面.利用JFrame提供最大的容器,然后设计各个面板,各个面板中添加所需要的组件,本程序中 ...

  6. JAVA三维可视化组件:Matplot 3D for JAVA(V2.0) 发布 欢迎使用JAVA平台 类似 Python 的 matplotlib

    目录 概述 V3.0介绍 V4.0介绍 组件下载及项目地址: V2.0版本主要改进: 概述 本人独立研发的一款JAVA平台可视化组件:Matplot3D for JAVA(V2.0) .基于JAVA ...

  7. java 数据分析库_超级好用的 Java 数据可视化库:Tablesaw

    本文适合刚学习完 Java 语言基础的人群,跟着本文可了解和使用 Tablesaw 项目.示例均在 Windows 操作系统下演示 本文作者:HelloGitHub-秦人 HelloGitHub 推出 ...

  8. 用 Java 实现一个远程控制客户端

    通过客户端远程操作其他电脑,关机,重启,注销等!是不是都很神奇?!这种正式软件常用于多媒体教学.远程协助.远程遥控设备等.这里我们通过案例,手把手一步步的实现整个过程,自己完成案例后,自然就不会再感觉 ...

  9. java开发可视化界面_java 可视化界面编程

    importjava.awt.*;importjava.awt.event.*;importjava.awt.Frame;publicclassawttest{publicstaticvoidmain ...

最新文章

  1. 微软正式发布Azure Storage上的静态网站
  2. 「机器学习速成」过拟合的风险和泛化
  3. python qthread 线程退出_线程:概念和实现
  4. 同软件多个线程设置不同ip_5-13网络编程(附带多线程死锁,线程通信)
  5. 【安骑士】安装失败问题分析
  6. R数据可视化--ggplot2定位之坐标系详解
  7. 《Spring Boot极简教程》附录4 Java编程简史
  8. linux内核模块编写,Linux内核模块编程
  9. NHibernate剖析:Mapping篇之Mapping-By-Code(1):概览
  10. java switch中标签重复_java程序 怎样把id相同的记录挑出来,分别存到不同的文件中,除了switch case,数据量很大,id种类很多。...
  11. 第三百七十二天 how can I 坚持
  12. 百家cms v4.1.4漏洞
  13. php1108脱机使用,电脑打印机脱机怎么重新连接
  14. Unity HDRP中代码动态修改天空盒以及其他环境参数
  15. Vuex_Todos
  16. 直流电机驱动模块介绍
  17. 报错Found existing installation: tensorflow 1.2.1
  18. 基于双月数据集利用最小二乘法进行分类
  19. 【线性代数】线性组合,线性相关与生成子空间(linear combination, linear dependency span)
  20. 手机照片局部放大镜_揭秘“网红大片”里的“骗局”!用手机就能惊艳朋友圈...

热门文章

  1. uniapp人脸识别解决方案
  2. 如何成就百万点击的名博
  3. kafka命令行使用
  4. 地表最强之Android微信语音/腾讯会议通话录音
  5. Short-term load forecasting with an improved dynamic decomposition-reconstruction-ensemble approach
  6. 在局域网下怎样控制另一台电脑
  7. python boxplot 多组_Matlab boxplot for Multiple Groups(多组数据的箱线图)
  8. 如何购买和设置阿里云国际版的 Web 应用防火墙
  9. 灰度图像--图像分割 阈值处理之谷底阈值、峰顶平均
  10. linux待机唤醒_Linux睡眠唤醒机制--Kernel态