通过socket传送图片的问题
通过socket传送客户端屏幕图片,但接收端好像始终有数据接收,而接收的数据量会大于送出的图片大小,比较原图片与收到的文件十六进制数据完全不同,本人小白,请各位给我点指导,谢
部分代码如下:
客户端
public class Client{ public static void main( String[] args ) { try { Socket client = new Socket( "localhost", 5888 ); OutputStream sender = client.getOutputStream(); // 获取到屏幕图片数据 BufferedImage img = Screen.SnapShot(); // 生成文件 这里是可以生成图片的,大小大概为88.7kb ImageIO.write(img, "png", new File("screen.png")); // 转为比特后发送 sender.write( Client.getCompressedImage( img ) ); client.close(); } catch ( IOException e ) { e.printStackTrace(); } } /** * 图片转换为byte * @param image * @return */ public static byte[] getCompressedImage( BufferedImage image ) { byte[] imageData = null; try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write( image, "png", baos ); imageData = baos.toByteArray(); } catch ( IOException ex ) { imageData = null; } return imageData; }}
public class Server{ /** * @param args the command line arguments */ public static void main( String[] args ) { try { ServerSocket server = new ServerSocket( 5888 ); Socket client = server.accept(); InputStream inputStream = client.getInputStream(); Scanner sc = new Scanner( inputStream ); String result = ""; int counter = 0; while( sc.hasNextLine() ) { result += sc.nextLine(); // 直接限制到400行就停止了,不加的话会一直循环… if ( counter++ == 400 ) break; } byte[] resultToBytes = result.getBytes(); FileOutputStream out = new FileOutputStream( "test.png" ); // 生成的文件大于88.7kb 而且16进制与原图片的不同 out.write( resultToBytes ); out.close(); client.close(); } catch ( IOException e ) { e.printStackTrace(); } }}
private Scanner(Readable source, Pattern pattern) { assert source != null : "source should not be null"; assert pattern != null : "pattern should not be null"; this.source = source; delimPattern = pattern; buf = CharBuffer.allocate(BUFFER_SIZE); buf.limit(0); matcher = delimPattern.matcher(buf); matcher.useTransparentBounds(true); matcher.useAnchoringBounds(false); [color=#FF0000]useLocale(Locale.getDefault(Locale.Category.FORMAT));[/color] }
[解决办法]
c/s结构没玩过,帮顶!
[解决办法]
随着屏幕比例的大小延迟更明显
——正常,屏幕越大,压缩数据量越多,耗费内存越高
——比较值得改进的问题是,你的Client端程序做了两次:png压缩,而png压缩是压缩率较低且开销较高的压缩算法;
——建议先得到byte[] imgToBytes = Client.getCompressedImage( img );然后直接把这个字节数组写入文件就好了。
不时会出现一些异常情况,比如包的数量莫名奇妙的变大为25,包大小变了负值
——没有认真调试你的程序,不好说
——但我认为没必要拆包,直接整个byte数组扔给 OutputStream sender 就好了,拆包增加复杂度,浪费内存,浪费copy时间,而且关键是没看到带来了啥好处
不知道将byte[]转为int那个方法是否有错?
——除了最后那个以外,没啥问题:
byte[] targets = new byte[4];
targets[0] = (byte) (res & 0xff);// 最低位
targets[1] = (byte) ((res >> 8) & 0xff);// 次低位
targets[2] = (byte) ((res >> 16) & 0xff);// 次高位
targets[3] = (byte) (res >>> 24);// 最高位,无符号右移。
——但逻辑上来说,你原始值只要不是负数就应该不存在符号位问题
还有程序占用了较多的内存
——很正常,自己算算就知道了:
1024宽×768高×32位色彩 = 3MB
1920宽×768高×32位色彩 = 8.16MB
这都是实打实的内存开销。
[解决办法]
import com.sun.image.codec.jpeg.*; public static byte[] getCompressedImageAWT(BufferedImage image) { byte[] imageData = null; try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(baos); encoder.encode(image); imageData = baos.toByteArray(); } catch (IOException ex) { ex.printStackTrace(); } return imageData; }