日期:2014-05-20  浏览次数:20733 次

通过socket传送图片的问题
通过socket传送客户端屏幕图片,但接收端好像始终有数据接收,而接收的数据量会大于送出的图片大小,比较原图片与收到的文件十六进制数据完全不同,本人小白,请各位给我点指导,谢

部分代码如下:

客户端
Java code

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;
    }
}



服务端
Java code

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();
        }
    }
}



------解决方案--------------------
读取二进制流,请不要用Scanner,这个是用来处理文本流的,也就是必须是可识别字符才能正确处理。
------解决方案--------------------
Java code
    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那个方法是否有错?