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!
Example of how to send an Object over a Socket in Java. Socket socket = new Socket("localhost", 7777);
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.
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.
Yes, Socket and ServerSocket use TCP/IP.
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();
}
}
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();
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With