Sending one image works, but when i repeat the cycle again it just doesn't work.
my Client side code (excerpt):

for(int i=0;i<50;i++){//fromServer.contains("image")
    img = ImageIO.read(in);
    System.out.println("Got image.");
    label = new JLabel(new ImageIcon(img));
    scrollPane.setViewportView(label);
    fromServer = reader.readLine();
    }

On the client side i have this output

Got image.
Got image.
Exception in thread "Thread-2" java.lang.NullPointerException
        at javax.swing.ImageIcon.<init>(ImageIcon.java:190)
        at screenviewer.DataReciever.run(DataReciever.java:84)

my Server side code (excerpt):

dim = toolkit.getScreenSize();
            System.out.println("Got screen size:" + dim.width + "x" + dim.height);
            captureSize = new Rectangle(dim);

            for (int i = 0; i < 50; i++) {
                bufferedImage = robot.createScreenCapture(captureSize);
                ImageIO.write(bufferedImage, "JPG", out);
                System.out.println("Sent image!");
                //out.flush(); this didn't helped
            }

Please help this is for my "end of the year thesis". I need to finish my project fast.

Recommended Answers

All 13 Replies

What happens if you use more primitive write/read methods that write bytes and read bytes and build an image from those bytes vs using ImageIO?
You'd have to send a header with the length of the image data.

Or write a small self contained program that demos the problem and post it.

I tried to do the primitive way , but how to get the image's size?

Or maybe you can help writing an image IO the grammar way... having a look at Image IO API i noticed i can use a ImageWriter to write into a stream... and it seems i should do it with these functions:

prepareWriteEmpty(IIOMetadata streamMetadata, ImageTypeSpecifier imageType, int width, int height, IIOMetadata imageMetadata, List thumbnails, ImageWriteParam param)// Begins the writing of a complete image stream, consisting of a single image with undefined pixel values and associated metadata and thumbnails, to the output.

and end it with

endWriteEmpty()//Completes the writing of a new image that was begun with a prior call to prepareWriteEmpty.

but there are a lot of params that i don't understand. :S . And how knows if my interpretations are correct...

how to get the image's size

To get size of image, use ImageIO to write the image into a ByteArray

my Client side:

//Accepting connection and initilizing streams
            Socket incoming = conn.accept();
            System.out.println("Data connection Established");
            in = incoming.getInputStream();
            reader = new BufferedReader (new InputStreamReader(in));
            
            //Reading from server
            fromServer = reader.readLine();
            System.out.println("First message from dataSender:"+fromServer);

            //Getting the images
            BufferedImage buffImg = null;
            for(;fromServer.contains("image");){
                str = fromServer.split(" ");
                byteArray = new byte [(int) Integer.getInteger(str[2])];
                in.read(byteArray);
                System.out.println("Got image.");
                
                //Converting the image
                ByteArrayInputStream byteArrayI = new ByteArrayInputStream(byteArray);
                buffImg = ImageIO.read(byteArrayI);

                //Displaying the image
                label = new JLabel(new ImageIcon(buffImg));
                scrollPane.setViewportView(label);
                fromServer = reader.readLine();
            }

            in.close();
            conn.close();
            System.out.println("Data Reciever has ended!");

And Server side:

dim = toolkit.getScreenSize();
            System.out.println("Got screen size:" + dim.width + "x" + dim.height);

            captureSize = new Rectangle(dim);


            for (int i = 0; i < 50; i++) {
                bufferedImage = robot.createScreenCapture(captureSize);
                System.out.println("Got image!");

                byte [] byteArray = byteArrayO.toByteArray();
                writer.println("image " + dim.width + "x" + dim.height+ " "+(byteArray.length));
                System.out.println("Sent dimensions.");
                
                out.write(byteArray);
                System.out.println("Sent image!");
                out.flush();
            }

Client's output (not showing any image):

Data connection Established

Server wrote (probably) 50 messages (did 50 iterations). Where did i go wrong?

It looks like the loop in the server will go around 50 times and print out 3 lines each time it goes around.

Where did i go wrong?

I can't tell what is right or wrong. I can only see the code and what it does.
What do you want the code to do?

What do you want the code to do?

I thought the title was there for making it clear.

I want to send multiple images over a socket and show them on the client side.
It looks like my code stops on this line.

fromServer = reader.readLine();

Can you please tell me why, if your see the problem? And provide a solution, perhaps, please.

The title of the thread is a problem statement.
Its not a description of what particular pieces of code are to do.

fromServer = reader.readLine();

Is there any data to be read? Use the available() to determine if there are.
Read the API doc. Some read methods will block until there is data available.

I didn't created my PrintWriter from the server side correct, that was the problem.
However...now i have :

Data connection Established
First message from dataSender:image 1440x900 0
Exception in thread "Thread-2" java.lang.NullPointerException
        at screenviewer.DataReciever.run(DataReciever.java:92)

The last zero there is the size of the image in bytes. That's strange because my image is still there (1440x900). Perhaps the conversion to byte array wasn't successful. Any hints?

Nevermind about my previous post.I corrected the error but didn't managed to edit it in time.
My client side code:

//Accepting connection and initilizing streams
            Socket incoming = conn.accept();
            System.out.println("Data connection Established");
            in = incoming.getInputStream();
            reader = new BufferedReader (new InputStreamReader(in));

            //Reading from server
            fromServer = reader.readLine();
            System.out.println("First message from dataSender:"+fromServer);

            //Getting the images
            BufferedImage buffImg = null;
            for(;fromServer.contains("image");){//fromServer.contains("image")
                str = fromServer.split(" ");
                byteArray = new byte [Integer.parseInt(str[2].trim())];
                in.read(byteArray);
                System.out.println("Got image.");
                
                //Converting the image
                ByteArrayInputStream byteArrayI = new ByteArrayInputStream(byteArray);
                buffImg = ImageIO.read(byteArrayI);

                //Displaying the image
                label = new JLabel(new ImageIcon(buffImg));
                scrollPane.setViewportView(label);
                fromServer = reader.readLine();
                System.out.println(""+fromServer);
            }

            in.close();
            conn.close();
            System.out.println("Data Reciever has ended!");

Client side output:

Data connection Established
First message from dataSender:image 1440x900 95895
Got image.
X`ߥQLCw7F)Pw7F)Pw7F)Pw7F)Pw7F)Pw7F)Pw7F)Pw7F)Pw7F)Pw7F)Pw7F)Pw7F)Pw7F)Pw7F)Pw7F)Pw7F)Pw7F)Pw7F)Pw7F)Pw7F)Pw7F)Pw7F)Pw7F)Pw7F)"

Server side code:

dim = toolkit.getScreenSize();
            captureSize = new Rectangle(dim);

            for (int i = 0; i < 50; i++) {
                bufferedImage = robot.createScreenCapture(captureSize);
                System.out.println("Got image!");

                byteArrayO = new ByteArrayOutputStream();
                ImageIO.write(bufferedImage,"jpg",byteArrayO);
                byte [] byteArray = byteArrayO.toByteArray();
                str = "image " + dim.width + "x" + dim.height+ " "+(byteArray.length);
                writer.println(str);
                System.out.println(str);
                
                out.write(byteArray);
                System.out.println("Sent image!");
                //out.flush();
            }

Server side output:

Got image!
image 1440x900 95895
Sent image!
Got image!
image 1440x900 95981
java.net.SocketException: Broken pipe
        at java.net.SocketOutputStream.socketWrite0(Native Method)
        at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
        at java.net.SocketOutputStream.write(SocketOutputStream.java:124)
        at myserver.DataSender.sendImage(DataSender.java:98)
        at myserver.DataSender.run(DataSender.java:77)

I do manage to get a image on the other side, but it's half-way interrupted. I've attached a screenshot. Is it because i'm capturing my own screen, or because the size wasn't estimated correct. Please help me understand where the estimation was done wrong, if it's the second.

You don't show what the writer and out objects are and how they are initialized.
Your code doesn't show what is in the str array. You're assuming its correct.
System.out.println(""+fromServer);
vs
System.out.println("Msg3="+fromServer); // put an id on ALL printouts

I took your code and tried to get it to work. I couldn't get it to work with the way you have the I/O classes wrapped. I removed a wrap and got it to work.
Suggestion: instead of sending a String (computers don't read Strings), reserve some fixed number of bytes at the beginning of the transmission to hold whatever you need to pass to the other side. If you do need to send a String, send its length followed by its chars.
My Code:

import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.util.*;
import javax.imageio.*;
import java.net.*;

public class SendScreen {
   final static int NbrToSend = 20;

   final static int port = 8888;

  class ClientSide {
    int ix = 1;
    InputStream in;

    public ClientSide() {
       try{
            ServerSocket conn = new ServerSocket(port);
            //Accepting connection and initilizing streams
            Socket incoming = conn.accept();
            System.out.println("Data connection Established");
            in = incoming.getInputStream();
//            BufferedReader reader = new BufferedReader (new InputStreamReader(in));


            String fromServer = getString();
            System.out.println("First message from dataSender:"+fromServer);

            //Getting the images
            BufferedImage buffImg = null;
            for(;fromServer.indexOf("image") >= 0;){//fromServer.contains("image")
                String[] str = fromServer.split(" ");
                int nbrToRead = Integer.parseInt(str[2].trim());
                System.out.println("len=" + nbrToRead + ", avail=" + in.available());
                byte[] byteArray = new byte[nbrToRead];

                int nbrRd = 0;
                int nbrLeftToRead = nbrToRead;
                while(nbrLeftToRead > 0){ 
                  int rd =in.read(byteArray, nbrRd, nbrLeftToRead);
                  if(rd < 0)
                    break;
                  nbrRd += rd; // accumulate bytes read
                  nbrLeftToRead -= rd;
                  System.out.println("Got part of image. rd=" + rd + ", nbrLeftToRead= " + nbrLeftToRead
                                    + " avail=" + in.available());
                }

                System.out.println("Got image. nbrToRead=" + nbrToRead + ", nbrRd=" + nbrRd);
                
                //Converting the image
                ByteArrayInputStream byteArrayI = new ByteArrayInputStream(byteArray);
                buffImg = ImageIO.read(byteArrayI);

                File of = new File("RecvdImg" + ix++ + ".jpg");
                ImageIO.write(buffImg, "jpg" ,of);

                //Displaying the image
//                JLabel label = new JLabel(new ImageIcon(buffImg));
//                scrollPane.setViewportView(label);
                fromServer = getString();
                System.out.println("Client: Next: " + fromServer);
                if(fromServer == null)
                  break;
            }   // end for(i)

            in.close();
            conn.close();
            System.out.println("Client: Data Reciever has ended!");
          }catch(Exception x) {
            x.printStackTrace();
          }
       }

       String getString() throws IOException {
            byte[] strIn = new byte[100];
            int ix = 0;
            while(true) {
               int rd = in.read();
               if((rd == (int)'\n') || (rd < 0))
                 break;
               strIn[ix++] = (byte)rd;
            }
            System.out.println("created str ix=" + ix);
            if(ix == 0)
              return null;
            return new String(strIn, 0, ix);
       }
    } // end class

    //-----------------------------------------------------------------------------
    class Server {
         Dimension dim;
         Rectangle captureSize;
         BufferedImage bufferedImage;

         public Server() {
           try{
            Robot  robot = new Robot();
            dim = new Dimension(300, 300); //toolkit.getScreenSize();
            captureSize = new Rectangle(dim);

            Socket soc = new Socket("127.0.0.1", port);
            OutputStream out = soc.getOutputStream();

            for (int i = 0; i < NbrToSend; i++) {
                bufferedImage = robot.createScreenCapture(captureSize);
                System.out.println("Captured image!");

                ByteArrayOutputStream byteArrayO = new ByteArrayOutputStream();
                ImageIO.write(bufferedImage,"jpg",byteArrayO);
                byte [] byteArray = byteArrayO.toByteArray();
                String str = "image " + dim.width + "x" + dim.height+ " " + (byteArray.length) 
                                   + " img=" + i + "\n";
                byte[] strB = str.getBytes();
                out.write(strB);
//                writer.println(str);
                System.out.println("sent: " + str + " nbrBytes=" + strB.length);
                
                out.write(byteArray);
                System.out.println("Sent image! nbrBytes=" + byteArray.length);
                //out.flush();
            } // end for(i)
           }catch(Exception x) {
             x.printStackTrace();
           }
         }
     } // end class Server

     //------------------------------------------------------------------------
     public SendScreen() {
        Thread t1 = new Thread(new Runnable(){
           public void run() {
             new  ClientSide();
           }
        });
        t1.start();
        try{Thread.sleep(500);}catch(Exception x){}
        Thread t2 = new Thread(new Runnable(){
           public void run() {
             new  Server();
           }
        });
        t2.start();
     }

     public static void main(String[] args) {
         new SendScreen();
     }
}
commented: Thanks a lot! +3

Thanks very much. That did it.
I have some questions concerning the code you changed:
1. Why does this logic work:

while(nbrLeftToRead > 0){
                  int rd =in.read(byteArray, nbrRd, nbrLeftToRead);
                  if(rd < 0)
                    break;
                  nbrRd += rd; // accumulate bytes read
                  nbrLeftToRead -= rd;
                  System.out.println("Got part of image. rd=" + rd + ", nbrLeftToRead= " + nbrLeftToRead
                                    + " avail=" + in.available());
                }

I mean, "int rd =in.read(byteArray, nbrRd, nbrLeftToRead);", if you read from the input stream into a byteArray, from the offset nbrRD, nbrLeftToRead bytes then they should get read all at once. Which is not the case when i run it.

2. Why did you changed this line

fromServer.indexOf("image") >= 0

Is it because its faster/optimized?

then they should get read all at once

Not necessarily. The packets are blocked out to 8192 or some size and might not all get sent together. The read can only get some of the data and must go back and get more.
I used indexOf() because I have an older, much faster compiler about java version 1.4 that I use vs one for 1.6.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.