转自http://fluagen.blog.51cto.com/146595/425818
用socket做长连接时,出现了内存溢出的错误。搞了4天的时间总算是搞定了。
现总结下:
1.socket一般分为短连接和长连接。
长连接是一旦一个客户端登陆上服务器,其与服务器之间的连接就不关闭,不管他们之间进行了多少次交易,直到客户端退出登陆或网络出现故障。这种技术在联机交易系统实现有利于提高效率。
长:connect连上后不断开,
2.短连接进行一次连接做完业务逻辑处理后就关闭连接,关闭了socket连接也就释放了socket所占用的资源,所以不会出现内存溢出的问题。
长连接一般是连接上服务器后,会做一个循环的业务逻辑处理。如果这个时候我们不得不在循环里创建对象发送到服务器端做处理然后服务器端(反之亦然),那么就有可能出现内存溢出的问题。
例如下面实现的远程桌面的程序:
服务器端
- com.hjdf.calis.cvrs.util.CvrsSystem.println(serverPort
+ " 等待连接中......"); -
serverSkt.setSoTimeout(10*60*1000);//服务器端的超时时间 -
clientSkt = serverSkt.accept(); -
com.hjdf.calis.cvrs.util.CvrsSystem.println(serverPort+"与" + -
clientSkt.getInetAddress() + " 建立连接"); -
clientSkt.setSoTimeout(60*1000);//客户端的超时时间 -
ObjectOutputStream out = new ObjectOutputStream(clientSkt.getOutputStream()); -
ObjectInputStream in= new ObjectInputStream(clientSkt.getInputStream()); -
-
ObjectOutputStream pipeout = new ObjectOutputStream(outputstream); -
ObjectInputStream pipein = new ObjectInputStream(inputstream); -
String pipstr="GET"; -
if(iswrite){ -
pipstr = (String) pipein.readObject(); -
if (pipstr != null) { -
out.writeObject(pipstr); -
} -
iswrite =false; -
}else{ -
out.writeObject(pipstr); -
out.flush(); -
} -
ScreenImageInfo screenInfo= (ScreenImageInfo)in.readObject(); -
while(screenInfo!=null){ -
pipeout.writeObject(screenInfo); -
if(iswrite){ -
pipstr = (String) pipein.readObject(); -
if (pipstr != null) { -
out.writeObject(pipstr); -
} -
iswrite =false; -
}else{ -
out.writeObject(pipstr); -
out.flush(); -
} -
screenInfo= (ScreenImageInfo)in.readObject(); -
-
}
客户端
- ObjectInputStream
in= new ObjectInputStream(clientSkt.getInputStream()); -
Toolkit toolkit = Toolkit.getDefaultToolkit(); -
Dimension screenSize = toolkit.getScreenSize(); -
Rectangle screenRect = new Rectangle(screenSize); -
Robot robot = new Robot(); -
ObjectOutputStream out = new ObjectOutputStream(clientSkt.getOutputStream()); -
while ( (clientCom = (String) in.readObject()) != null) { -
-
if (clientCom.equals("GET")) { -
BufferedImage image = robot.createScreenCapture(screenRect); -
ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream(); -
JPEGImageEncoder encoder = -
JPEGCodec.createJPEGEncoder(byteOutStream); -
-
JPEGEncodeParam param = encoder.getDefaultJPEGEncodePara m(image); -
param.setQuality(0.5f, false); -
encoder.setJPEGEncodeParam(param); -
encoder.encode(image); -
ScreenImageInfo imageInfo = -
new ScreenImageInfo(byteOutStream.toByteArray()); -
out.writeObject(imageInfo); -
} -
}
修改服务器端和客户端,解决内存溢出:
服务器
- com.hjdf.calis.cvrs.util.CvrsSystem.println(serverPort
+ " 等待连接中......"); -
serverSkt.setSoTimeout(10*60*1000);//服务器端的超时时间 -
clientSkt = serverSkt.accept(); -
com.hjdf.calis.cvrs.util.CvrsSystem.println(serverPort+"与" + -
clientSkt.getInetAddress() + " 建立连接"); -
clientSkt.setSoTimeout(60*1000);//客户端的超时时间 -
-
while(true){ -
ObjectInputStream in= new ObjectInputStream(clientSkt.getInputStream()); -
ObjectOutputStream pipeout = new ObjectOutputStream(outputstream); -
ScreenImageInfo screenInfo= (ScreenImageInfo)in.readObject(); -
if(screenInfo!=null){ -
pipeout.writeObject(screenInfo); -
} -
}
客户端
- Toolkit
toolkit = Toolkit.getDefaultToolkit(); -
Dimension screenSize = toolkit.getScreenSize(); -
Rectangle screenRect = new Rectangle(screenSize); -
Robot robot = new Robot(); -
while(true){ -
ObjectOutputStream out = new ObjectOutputStream(clientSkt.getOutputStream()); -
BufferedImage image = robot.createScreenCapture(screenRect); -
ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream(); -
JPEGImageEncoder encoder = -
JPEGCodec.createJPEGEncoder(byteOutStream); -
-
JPEGEncodeParam param = encoder.getDefaultJPEGEncodePara m(image); -
param.setQuality(0.5f, false); -
encoder.setJPEGEncodeParam(param); -
encoder.encode(image); -
ScreenImageInfo imageInfo = -
new ScreenImageInfo(byteOutStream.toByteArray()); -
out.writeObject(imageInfo); -
}