[英]Java send screenshot over socket
我正在制作一个恶作剧程序,但无论如何都有点用处。
我目前正在尝试做的是从客户端获取屏幕截图并在服务器上打开屏幕截图作为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);
}
}
这部分服务器代码是一个新线程,创建一个新的套接字和一个新的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();
}
}
}
在服务器端,我添加了另一行,在本地创建图像只是为了解决任何问题。
提前致谢
你假设read()
填充缓冲区。 规范中没有任何内容表明这一点。 尝试这个:
int size = in.readInt();
byte[] imageAr = new byte[size];
in.readFully(imageAr);
readInt()
和readFully()
都保证读取正确的量,或者在该尝试失败。
你也在发送端给自己一个艰难的时间。 尝试这个:
out.writeInt(size);
out.write(baos.toByteArray());
out.close();
请注意, close()
flush()
之前的flush()
是多余的,但是应该关闭套接字周围的最外面的输出流,而不是套接字,以使其自动刷新。
事实上,当您在每个图像之后关闭连接时,您可以摆脱大小字和字节数组输入/输出流,并直接从/向套接字执行ImageIO.read/write
。 它会节省大量内存。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.