5

I can display a single image received, but now I want to receive and write multiple images on my disk which will be sent from Android client after every 5 seconds.

Socket sock = servsock.accept();
dataInputStream = new DataInputStream(sock.getInputStream());
dataOutputStream = new DataOutputStream(sock.getOutputStream());
System.out.println("Accepted connection : " + sock); 

dataInputStream = new DataInputStream(sock.getInputStream());

byte[] base64=dataInputStream.readUTF().getBytes();

byte[] arr=Base64.decodeBase64(base64);

FileOutputStream imageOutFile = new FileOutputStream("E:\\image.jpeg");
imageOutFile.write(arr);
syb0rg
  • 8,057
  • 9
  • 41
  • 81
Wajih Ahmed
  • 99
  • 1
  • 2
  • 7

3 Answers3

3

You'll need to build a protocol between your client and the server.

If the image size is constant you just have to loop over the input-stream and keep buffering until you get the fixed number of bytes and write all the already buffered image.

Otherwise you'll need to add some metadata indicating the size of the images; e.g. you could use a simple format like this :

[size1][image1][size2][image2][size3][image3]

with [size-i] occupying a fixed amount of space and [image-i] the size of the ith image.

But above all don't be tempted to do such a naive protocol as processing an image, sleeping 5 seconds and retrieving the next one because the exact time could vary a lot between each image due to client, network or the server (your code and/or the file-system).

Pragmateek
  • 13,174
  • 9
  • 74
  • 108
2

Little changes:

Socket sock = servsock.accept();
dataInputStream = new DataInputStream(sock.getInputStream());
dataOutputStream = new DataOutputStream(sock.getOutputStream());
System.out.println("Accepted connection : " + sock); 

int imagesCount = dataInputStream.readInt();
for (int imgNum = 0; imgNum < imagesCount; imgNum++) {
    int imgLen = dataInputStream.readInt();
    byte[] base64 = new byte[imgLen];
    dataInputStream.readFully(base64);

    byte[] arr = Base64.decodeBase64(base64);

    FileOutputStream imageOutFile = new FileOutputStream("E:\\image"+imgNum+".jpeg");
    imageOutFile.write(arr);
}
ggrandes
  • 2,067
  • 22
  • 16
  • 1
    VG but I would get rid of the base64 encoding and just use DataInputStream.readFully(). – user207421 Jan 06 '13 at 02:12
  • 1
    In this case... `for (.....) { int imgLen = dataInputStream.readInt(); byte[] arr = new byte[imgLen]; dataInputStream.readFully(arr); // [...cut...]` – ggrandes Jan 06 '13 at 06:42
  • I am getting this error Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at server.main(server.java:52) – Wajih Ahmed Jan 06 '13 at 07:53
  • 1
    more likely thing is that you receive a wrong imgLen... post the client code to see what are you sending ... – ggrandes Jan 06 '13 at 08:07
  • i think i need to use threads in order to read continuously from inputstream – Wajih Ahmed Jan 06 '13 at 09:01
  • @WajihAhmed No you don't, you need to solve your protocol problem whereby you are reading the wrong image length value, as ggrandes suggested. Thinking about threads is just displacement activity. Of course if you get rid of the base64 encoding you have to remove it from the sender as well. – user207421 Jan 06 '13 at 09:06
  • i have been able to display a single image through base64encoding so its working fine.now the only variation i want to do is i want to receive multiple images from client.any help on this particular point would be greatly appreciated. – Wajih Ahmed Jan 06 '13 at 09:10
  • 1
    @WajihAhmed The base64 encoding sheme isn't suitable. For one thing it limits you to images whose base64 encoding is less than 64k. You need to rethink this. – user207421 Jan 06 '13 at 09:12
  • the code i initially posted is working but the connection is closed after it recieves 1 image from client.i want the connection to remain active and until client is sending data it writes to output file.... – Wajih Ahmed Jan 06 '13 at 09:12
  • @WajihAhmed So don't close the connection. What's the question here? – user207421 Jan 06 '13 at 09:13
  • ill get rid off it later on but currently i want to accomplish this task of recieving multiple images. – Wajih Ahmed Jan 06 '13 at 09:14
  • @WajihAhmed You have to get rid of closing the connection *now.* – user207421 Jan 06 '13 at 09:15
  • @EJP the question is i am recieving multiple images and i want to store it on computer... – Wajih Ahmed Jan 06 '13 at 09:16
  • @WajihAhmed I can read the question thanks. The problem at the moment appears to be that you can't read the answers. If your problem is that the connection is closed, you have to remove the code that closes the connection. I don't see how anybody can help you until you take some notice of what you've already been told here. – user207421 Jan 06 '13 at 09:17
  • yes i am not closing the connection but right now its giving outofmemory error..... when i tried to use the code provided by you .... – Wajih Ahmed Jan 06 '13 at 09:17
  • 1
    @WajihAhmed I didn't provide any code: ggrandes did. If you are getting `OutOfMemoryError` you are clearly receiving an incorrect image length word, as ggrandes already suggested. You need to investigate that. For example, *print* it when you receive it. Are you *sending* a length word? The changes suggested in this answer require corresponding changes at the sender, which you should be able to work out for yourself. Have you done so? – user207421 Jan 06 '13 at 09:18
  • if you can focus on my original code is there a way to improvise it for receiving multiple images through a loop just ignore ggrandes code.. – Wajih Ahmed Jan 06 '13 at 09:22
  • 1
    improve your code without closing socket to receive more than one... is not posible... if you want use the same socket, you must need a protocol... if no protocol, you need open/close sockets for every image. – ggrandes Jan 06 '13 at 09:27
  • @WajihAhmed It is futile to discuss this matter further without taking the sending code into account. If the sending code is closing the connection after sending each image, you will have to change it. If the sending code is sending images whose base-64 encoding is >= 64k, you will have to change it. – user207421 Jan 06 '13 at 09:30
  • the error got fixed. i turned off sock.close and receiving data in a while loop and it worked like a charm. thanx for everyones interest. – Wajih Ahmed Jan 06 '13 at 18:59
0

If you are having multiple clients and a single server. Try multi-threading. Sample piece of code:

public static void main(String[] args){
    try {
        servSocket = new ServerSocket(xxxx);

        while(true)
        {

            socket = servSocket.accept();

            ClientNum++;

            for(int i=0;i<10;i++){ //this for eg accepts 10 clients, with each client assigned an ID. 

                if(threads[i]==null){
                    sockets[i]=socket; 

In your "run", you can call each of these clients by their respective ID and perform the reqd function you need. Not sure how clear this is. If needed, I can send you the entire code I have which is kinda similar to what you are doing.

doelleri
  • 19,232
  • 5
  • 61
  • 65