Java通过套接字发送屏幕截图

Java通过套接字发送屏幕截图

问题描述:

我正在开发一个恶作剧程序,但无论如何都有点用处。Java通过套接字发送屏幕截图

目前我试图做的是从客户端获取屏幕截图并在服务器上以JFrame的形式打开屏幕截图。

经过多次尝试,我发现这个未解决的问题How to send images through sockets in java?

截图通过,但它的切碎,只有约120-135kb完成。在*投票答案中,他在客户端有Thread.sleep(),然后我关闭了连接,但是我没有尝试它,它被切断了,所以我尝试了它,但是它仍然被切回。我的客户端读取输入数据的类在循环中,每100ms运行一次,所以我认为它的循环速度太快,所以我将其增加到1000ms,并且它仍然被切碎。

我试着用另一种答案的东西就在同线程不同而改变在服务器端的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(); 
       *UI.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显示的屏幕截图。我为什么要这样做?在另一个线程上,我读到只有在套接字关闭时才会发送图像。所以,因为我不想要主要的套接字关闭,否则我失去了连接,我创建了另一个套接字,暂时只会打开屏幕截图。

客户

​​

在服务器端,我补充说,在本地创建的图像只是如果有什么来解决,通过另一条线。

在此先感谢

你假设read()填充缓冲区。说明中没有这样说。试试这个:

int size = in.readInt(); 
byte[] imageAr = new byte[size]; 
in.readFully(imageAr); 

readInt()readFully()保证读取正确的金额,或者在尝试失败。

你也给自己在发送端很难。试试这个:

out.writeInt(size); 
out.write(baos.toByteArray()); 
out.close(); 

注意flush()之前close()是多余的,但你应该关闭外侧输出流套接字,而不是插座周围,让它自动刷新。

事实上,当你在每个图像之后关闭连接时,你可以摆脱大小字和字节数组输入/输出流,并直接从/到插槽执行ImageIO.read/write。这将节省大量的内存。

+0

我肯定会从这个变化中获得更好的结果。实际上,我在发送端保留'size'作为字节数组,并在读取端保存'size',并且我获得了大部分屏幕,但屏幕的右侧和底部都被捕获。这可能与我使用RDP进行远程编程有关。非常感谢! – xR34P3Rx

+0

考虑到空间和时间成本,我仍然会删除大小字和字节数组流。不要使简单的事情复杂化。 – EJP

+0

hehe ... @EJP,我可以问一下吗? out.writeInt(size); out.write(baos.toByteArray()); out.close(); 对我来说很好。除非我得到规模价值,...我从哪里得到它?图像的int大小或什么? – gumuruh