使用Socket发送和接收图像

时间:2017-12-12 05:18:50

标签: java sockets netty

在使用ServerSocketSocket的Java中,我可以使用以下代码在本地网络中传输图像文件:

发送

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

接收

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

}

如何使用Socket在Netty中执行此操作?

我的处理程序

@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
            */

        }


    }

我一直在Netty中搜索这个例子,我只找到了通过Http发送的示例,但我仍然不知道该怎么做。顺便说一句,我在我的管道中使用ObjectEncoder()ObjectDecoder(ClassResolvers.cacheDisabled(null))

2 个答案:

答案 0 :(得分:0)

解决我的问题:

<强>发送

  1. 获取文件
  2. 转换为字节数组
  3. 发送
  4. <强>接收

    1. 获取接收字节数组
    2. 转换回图片
    3. 保存
    4. 我的处理程序

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

      我不确定其他人是如何在Netty上实际做到的,但这就是我如何解决它。

      注意:使用此解决方案传输大文件时可能会出现问题。

答案 1 :(得分:0)

您的方法很好但是在传输大文件时可能会遇到问题(不仅限于图像文件)。我建议您查看here中的ChuckedWriteHandler,文档写得很好。