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周期。。。无论如何,我认为睡眠可以提高性能,因为在发送图像后,客户端可以在再次等待请求之前“休息”。