简体   繁体   中英

Sending and Receiving image using Socket

In Java with ServerSocket and Socket I can transfer image file using the below code in a Local Network:

Send

public class Send {

    public static void main(String[] args) throws Exception {
        Socket socket = new Socket(serverIP, serverPORT);
        OutputStream outputStream = socket.getOutputStream();

        BufferedImage image = ImageIO.read(new File("test.jpg"));

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ImageIO.write(image, "jpg", byteArrayOutputStream);

        byte[] size = ByteBuffer.allocate(4).putInt(byteArrayOutputStream.size()).array();
        outputStream.write(size);
        outputStream.write(byteArrayOutputStream.toByteArray());
        outputStream.flush();

        socket.close();
    }
}

Receive

public class Receive {

    public static void main(String[] args) throws Exception {
        ServerSocket serverSocket = new ServerSocket(serverPORT);
        Socket socket = serverSocket.accept();
        InputStream inputStream = socket.getInputStream();

        byte[] sizeAr = new byte[4];
        inputStream.read(sizeAr);
        int size = ByteBuffer.wrap(sizeAr).asIntBuffer().get();

        byte[] imageAr = new byte[size];
        inputStream.read(imageAr);

        BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageAr));

        ImageIO.write(image, "jpg", new File("test2.jpg"));

        serverSocket.close();
    }

}

How can I do it in Netty using Socket?

My Handler

@Override
    protected void channelRead0(ChannelHandlerContext ctx, Object o) throws Exception {
        Channel currentChannel = ctx.channel();
        System.out.println(TAG + "MESSAGE FROM SERVER - " + currentChannel.remoteAddress() + " - " + o);

        List<Object> msg = new ArrayList<>();
        msg.addAll((Collection<? extends Object>) o);

        /*If message in index 0 is Equal to IMAGE then I need to send an Image File*/
        if(msg.get(0).equals("IMAGE")){

            /*
                NO IDEA on how can I send it on Netty.
                I'm not sure if this will work or this is how should I do it.
            */

                BufferedImage image = ImageIO.read(new File("test.jpg"));
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                ImageIO.write(image, "jpg", byteArrayOutputStream);
                byte[] size = ByteBuffer.allocate(4).putInt(byteArrayOutputStream.size()).array();

                msg.clear(); //clear the List Object
                msg.add(0, "IMAGE_FILE"); //Add the Type of message with String
                msg.add(1, size); //Add the size
                msg.add(2, byteArrayOutputStream.toByteArray()); //Add the image file to send 
                sendMessage(ctx, msg);

            ctx.writeAndFlush(msg); //Finally Send it.
        }

        /*If message in index 0 is Equal to IMAGE_FILE then I need to make it viewable*/
        if(msg.get(0).equals("IMAGE_FILE")){

            /*
                NO IDEA on how to decode it as an Image file
            */

        }


    }

I keep on searching for any example of this in Netty and I only found the example with Sending via Http but still I don't know how to do it. By the way, I'm using ObjectEncoder() and ObjectDecoder(ClassResolvers.cacheDisabled(null)) in my Pipeline.

Solving my problem:

sending

  1. Get the file
  2. Convert to byte array
  3. Send

Receive

  1. Get the receive byte array
  2. Convert back to image
  3. Save

My Handler

@Override
    protected void channelRead0(ChannelHandlerContext ctx, Object o) throws Exception {
        Channel currentChannel = ctx.channel();
        System.out.println(TAG + "MESSAGE FROM SERVER - " + currentChannel.remoteAddress() + " - " + o);

        List<Object> msg = new ArrayList<>();
        msg.addAll((Collection<? extends Object>) o);

        /*If message in index 0 is Equal to IMAGE then I need to send an Image File*/
        if(msg.get(0).equals("IMAGE")){

            byte[] imageInByte;
            BufferedImage originalImage = ImageIO.read(new File("test.jpg"));

            // convert BufferedImage to byte array
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(originalImage, "jpg", baos);
            baos.flush();
            imageInByte = baos.toByteArray();
            baos.close();

            msg.clear(); //clear the List Object
            msg.add(0, "IMAGE_FILE"); //Add the Type of message with String
            msg.add(1, imageInByte); //Add the Converted image in byte
            ctx.writeAndFlush(msg); //Finally Send it.
        }

        /*If message in index 0 is Equal to IMAGE_FILE then I need to get and Save it to use later*/
        if(msg.get(0).equals("IMAGE_FILE")){

            try {

                byte[] imageInByte = (byte[]) msg.get(1); //Get the recieve byte
                // convert byte array back to BufferedImage
                InputStream in = new ByteArrayInputStream(imageInByte);
                BufferedImage bImageFromConvert = ImageIO.read(in);

                ImageIO.write(bImageFromConvert, "jpg", new File("test.jpg")); //Save the file

            } catch (IOException e) {
                System.out.println(e.getMessage());
            }

        }


    }

I'm not sure if how others actually do this on Netty but this how I solved it.

NOTE: you might have issue while transferring large file using this solution.

Your approach is fine but you might have issue while transferring large file in general (not only limited to image file). I would recommend you to take a look at ChuckedWriteHandler in here , the documentation is well-written to follow.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM