Java 通过套接字发送多个图像

Java 通过套接字发送多个图像,java,sockets,Java,Sockets,我想做的是: client connects to server server sends READY client takes screenshot and sends it server processes image server sends READY client takes screenshot and sends it server processes image ... 我有一个工作的客户端和服务器: Client() { try { socket

我想做的是:

client connects to server
server sends READY
client takes screenshot and sends it
server processes image

server sends READY
client takes screenshot and sends it
server processes image
...
我有一个工作的客户端和服务器:

Client() {

    try {
        socket = new Socket(host, 4444);
        in = new DataInputStream(socket.getInputStream());
        out = new DataOutputStream(socket.getOutputStream());
        int ix = 0;
        while (true) {
            switch (in.readInt()) {
            case Var.READY:
                image = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
                ByteArrayOutputStream byteArrayO = new ByteArrayOutputStream();
                ImageIO.write(image,"PNG",byteArrayO);
                byte [] byteArray = byteArrayO.toByteArray();
                out.writeInt(byteArray.length);
                out.write(byteArray);
                System.out.println("send screen " + ix++);
                break;
            }
        }
    } catch (UnknownHostException e) {
        System.err.println("Don't know about host");
        System.exit(1);
    } catch (IOException e) {
        System.err.println("Couldn't get I/O for the connection " + e.getMessage());
        System.exit(1);
    } catch (Exception e) {
        e.printStackTrace();
        System.exit(1);
    }
}
服务器:

 public class ServerWorker implements Runnable {

private Socket socket = null;

DataInputStream in = null;
DataOutputStream out = null;

ServerWorker() {

}

synchronized void setSocket(Socket socket) {
    this.socket = socket;
    try {
        in = new DataInputStream(socket.getInputStream());
        out = new DataOutputStream(socket.getOutputStream());
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    notify();
}

public synchronized void run() {
    int ix = 0;
    try {
        while (true) {
            out.writeInt(Var.READY);
            int nbrToRead = in.readInt();
            byte[] byteArray = new byte[nbrToRead];
            int nbrRd = 0;
            int nbrLeftToRead = nbrToRead;
            while(nbrLeftToRead > 0){ 
                int rd =in.read(byteArray, nbrRd, nbrLeftToRead);
                if(rd < 0)
                    break;
                nbrRd += rd; // accumulate bytes read
                nbrLeftToRead -= rd;
            }
            //Converting the image
            ByteArrayInputStream byteArrayI = new ByteArrayInputStream(byteArray);
            BufferedImage image = ImageIO.read(byteArrayI);
            System.out.println("received screen " + ix++);
            //image.flush();
            File of = new File("RecvdImg" + ix + ".jpg");
            ImageIO.write(image, "PNG" ,of);
            System.out.println("Sleeping 1..");
            Thread.sleep(1000);
        }
    } catch (Exception e) {
        e.printStackTrace();
        Thread.currentThread().interrupt();
    }
}
}
公共类ServerWorker实现可运行{
私有套接字=空;
DataInputStream in=null;
DataOutputStream out=null;
服务器工作者(){
}
同步无效设置插座(插座){
this.socket=socket;
试一试{
in=新的DataInputStream(socket.getInputStream());
out=新的DataOutputStream(socket.getOutputStream());
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
通知();
}
公共同步的无效运行(){
int ix=0;
试一试{
while(true){
out.writeInt(Var.READY);
int nbrToRead=in.readInt();
字节[]字节数组=新字节[NBRTREAD];
int nbrRd=0;
int nbrleefttoread=nbrread;
而(nbrleftRead>0){
int rd=in.read(字节数组、nbrRd、NBRLeftRead);
if(rd<0)
打破
nbrRd+=rd;//累积读取的字节数
NbleFTREAD-=rd;
}
//转换图像
ByteArrayInputStream byteArrayI=新的ByteArrayInputStream(byteArray);
buffereImage image=ImageIO.read(byteArrayI);
System.out.println(“接收屏幕”+ix++);
//image.flush();
文件类型=新文件(“RecvdImg”+ix+”.jpg);
ImageIO.write(图像“PNG”,共页);
System.out.println(“睡眠1..”;
睡眠(1000);
}
}捕获(例外e){
e、 printStackTrace();
Thread.currentThread().interrupt();
}
}
}
那么你会问什么问题呢? 我做得对吗? ActivityMonitor告诉我客户端经常占用大约40%的cpu,这不太好


只是想知道是否有人能为我指出提高代码效率的正确方向。

客户机可以检测图像是否已更改,如果未更改,则可以向服务器发送一个标志,指示重复使用以前收到的图像。或者,您可以“区分”图像,只将更改的区域发送到服务器,服务器将重新组合图像。这降低了带宽使用率,也可能降低了CPU使用率


此外,客户端应该在接收无止境循环中休眠一段时间,在
开关之后

在我看来,您应该避免使用像这样的无限循环

while (true)
环状

while(!connectionAborted)
在这种情况下,你会更好

您还应该看看

SoTimeout根据您的参数,在特定时间后取消读取过程,即
in.readInt()


结果是在这一行抛出了一个
SocketTimeoutException
,但是您的代码没有卡在这一代码行上,并且可以对不同的用户输入做出反应。

谢谢,我将实现更改检测!对于睡眠,是否有必要像在.readInt()中那样阻塞,直到它接收到正确的东西?关于睡眠,无论如何,大多数时候客户端都应该被阻塞在.readInt()中的
in
中。但是我担心如果readInt本身消耗CPU周期。。。无论如何,我认为睡眠可以提高性能,因为在发送图像后,客户端可以在再次等待请求之前“休息”。