Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send images through sockets in java?

I am writing a client-server program and I want that to send an image. The code is the following:

//RECEIVER
while(true){
  try{
            socket = server.accept();

            out = new ObjectOutputStream(socket.getOutputStream());
            out.flush();
            in = new ObjectInputStream(socket.getInputStream());

            System.out.println("Connected to "+PORTA+".");

            while(!socket.isClosed()){ 
                System.out.println("\nPrint the action");
                azione = reader.readLine();

           if(azione.equals("screenshot")){

                    out.writeObject("screenshot");
                    out.flush();
                    BufferedImage screenshot = ImageIO.read(in);

                    ImageIO.write(screenshot, "jpg", new File("screenshot.jpg"));
                }
  }catch(Exception ex){
            System.out.println("Not connected.\n");
  } 
}

And the server:

while(true){ 
   try{
            socket = new Socket(INDIRIZZO, PORT);

            out = new ObjectOutputStream(socket.getOutputStream());
            out.flush();
            in = new ObjectInputStream(socket.getInputStream());

            while(!socket.isClosed()){
                try {
                  action = (String)in.readObject();
                  if(azione.equals("screenshot")){
                        BufferedImage screenshot = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
                        ImageIO.write(screenshot, "jpg", out);
                    }catch(Exception e){

                    }
            }
   }catch(Exception ex){
      //
   }
}

My problem is that the client receive the image only if I close the socket or the out stream, but I don't want that to happen. How can I bypass that? How can I send the image as bytes? Thanks!

like image 885
enemy Avatar asked Aug 01 '14 18:08

enemy


People also ask

How do you send an object to a socket?

Example of how to send an Object over a Socket in Java. Socket socket = new Socket("localhost", 7777);

What is difference between socket () and ServerSocket () class?

Here, two classes are being used: Socket and ServerSocket. The Socket class is used to communicate client and server. Through this class, we can read and write message. The ServerSocket class is used at server-side.

How do you use socket in Java?

To communicate over a socket connection, streams are used to both input and output the data. The socket connection is closed explicitly once the message to the server is sent. In the program, the Client keeps reading input from a user and sends it to the server until “Over” is typed.

Do Java sockets use TCP or UDP?

Yes, Socket and ServerSocket use TCP/IP.


2 Answers

The problem is that ImageIO.read waits for the end of the stream. Sockets send it only when you close it. (which makes sense)

What you want to do is to first send size of the image and on the receiver side to read the image as byte array.

public class Send {

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

        BufferedImage image = ImageIO.read(new File("C:\\Users\\Jakub\\Pictures\\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();
        System.out.println("Flushed: " + System.currentTimeMillis());

        Thread.sleep(120000);
        System.out.println("Closing: " + System.currentTimeMillis());
        socket.close();
    }
}


public class Receive {

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

        System.out.println("Reading: " + System.currentTimeMillis());

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

        System.out.println("Received " + image.getHeight() + "x" + image.getWidth() + ": " + System.currentTimeMillis());
        ImageIO.write(image, "jpg", new File("C:\\Users\\Jakub\\Pictures\\test2.jpg"));

        serverSocket.close();
    }

}
like image 67
jakub.petr Avatar answered Sep 27 '22 19:09

jakub.petr


You can find a (non-compiling) example at easywayprogramming.

I have simplified it and fixed the errors, I hope that this is a useful answer to your question.

Run the server first, then run the client as often as you want.

The example will take a screenshot of the upper left 200x100 pixels of your screen, send them to the server which will open a new window and display the screenshot.

GreetingServer.java

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.sql.SQLException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class GreetingServer extends Thread
{
       private ServerSocket serverSocket;
       Socket server;

       public GreetingServer(int port) throws IOException, SQLException, ClassNotFoundException, Exception
       {
          serverSocket = new ServerSocket(port);
          serverSocket.setSoTimeout(180000);
       }

       public void run()
       {
           while(true)
          { 
               try
               {
                  server = serverSocket.accept();
                  BufferedImage img=ImageIO.read(ImageIO.createImageInputStream(server.getInputStream()));
                  JFrame frame = new JFrame();
                  frame.getContentPane().add(new JLabel(new ImageIcon(img)));
                  frame.pack();
                  frame.setVisible(true);                  
              }
             catch(SocketTimeoutException st)
             {
                   System.out.println("Socket timed out!");
                  break;
             }
             catch(IOException e)
             {
                  e.printStackTrace();
                  break;
             }
             catch(Exception ex)
            {
                  System.out.println(ex);
            }
          }
       }

       public static void main(String [] args) throws IOException, SQLException, ClassNotFoundException, Exception
       {
              Thread t = new GreetingServer(6066);
              t.start();
       }
}

GreetingClient.java

import java.awt.AWTException;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.Socket;

import javax.imageio.ImageIO;

public class GreetingClient
{
    Image newimg;
    static BufferedImage bimg;
    byte[] bytes;

    public static void main(String [] args)
    {
        String serverName = "localhost";
        int port = 6066;
        try
        {
            Socket client = new Socket(serverName, port);
            Robot bot;
            bot = new Robot();
            bimg = bot.createScreenCapture(new Rectangle(0, 0, 200, 100));
            ImageIO.write(bimg,"JPG",client.getOutputStream());
            client.close();
        } catch(IOException | AWTException e) {
            e.printStackTrace();
        }
    }
}
like image 38
user2707001 Avatar answered Sep 27 '22 17:09

user2707001