2

When clients are connected to the server they should be able to send images to server, so the server can display the received images. I have used an AsyncTask at the server-end to do the task.

when one client is connected to the server everything seems fine, images are receiving from that client but when the next client connected it's not working, sometimes the first client gets disconnected or the images are not receiving from one client or both.

Can someone help me with this? am i doing anything wrong?

Server-end AsyncTask

  public static class FileServerAsyncTask extends AsyncTask {

    private Context context;
    private TextView statusText;

    public FileServerAsyncTask(Context context, View statusText) {
        this.context = context;
        this.statusText = (TextView) statusText;
    }

    @Override
    protected String doInBackground(Void... params) {

        class ClientWorker implements Runnable {
          private Socket client;
          private final File f;

        //Constructor
          ClientWorker(Socket client, File f) {
            this.client = client;
            this.f = f;
          }
          public void run(){                   
                try{

                File dirs = new File(f.getParent());
                if (!dirs.exists())
                    dirs.mkdirs();
                f.createNewFile();

                Log.d(WiFiDirectActivity.TAG, "server: copying files " + f.toString());
                InputStream inputstream = client.getInputStream();
                copyFile(inputstream, new FileOutputStream(f));                  
                } catch (IOException e) {
                    System.out.println("Accept failed: 4444");
                    System.exit(-1);
                  }

          }
      }

        try {
            ServerSocket serverSocket = new ServerSocket(8988);
            Log.d(WiFiDirectActivity.TAG, "Server: Socket opened");               
            boolean check = true;
            while(check){
               ClientWorker w;
                try{
            //server.accept returns a client connection
                final File f = new File(Environment.getExternalStorageDirectory() + "/"
                               + context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
                               + ".jpg");

                  w = new ClientWorker(serverSocket.accept(),f);
                 Thread t = new Thread(w);
                  t.start();
                  return f.getAbsolutePath();
               } catch (IOException e) {
                 System.out.println("Accept failed: 4444");
                  System.exit(-1);
                }
              }


            serverSocket.close();
            return null;
        } catch (IOException e) {
            Log.e(WiFiDirectActivity.TAG, e.getMessage());
            return null;
        }
    }

    @Override
    protected void onPostExecute(String result) {
        if (result != null) {
           statusText.setText("File copied - " + result);
            Intent intent = new Intent();
            intent.setAction(android.content.Intent.ACTION_VIEW);
           intent.setDataAndType(Uri.parse("file://" + result), "image/*");
           context.startActivity(intent);
       }

    }

    @Override
    protected void onPreExecute() {
        statusText.setText("Opening a server socket");
    }

}

public static boolean copyFile(InputStream inputStream, OutputStream out) {
    byte buf[] = new byte[1024];
    int len;
    try {
        while ((len = inputStream.read(buf)) != -1) {
            out.write(buf, 0, len);

        }
        out.close();
        inputStream.close();
    } catch (IOException e) {
        Log.d(WiFiDirectActivity.TAG, e.toString());
        return false;
    }
    return true;
}
senrulz
  • 121
  • 1
  • 2
  • 12
  • 1
    Worth reading this thread ... http://stackoverflow.com/questions/9654148/android-asynctask-threads-limits – John Sheridan Aug 03 '14 at 17:01
  • @John Sheridan Thank you for you answer. I know why it's not working now. can you look at the comment i've added in the first answer and suggest me something, i really appreciate it! – senrulz Aug 04 '14 at 06:42
  • 1
    You don't need to call `File.createNewFile()` if you're calling `new FileOutputStream` with the same `File,` in fact it is wasteful. – user207421 Aug 04 '14 at 07:02

1 Answers1

1

I think all you need is just changing these lines:

 w = new ClientWorker(serverSocket.accept(),f);
             Thread t = new Thread(w);
              t.start();
              return f.getAbsolutePath();

your problem is after the first client is connect you go out of doInbackground. you must use onProgressPublish() to send the intermidiate result and stay in loop and do not close server.

so after you connect to first client and sending him to socket you created, you go out of main loop by return f.getAbsolutePath(); and go out from server. all your code is correct except that for sending out intermediate result use function(onProgressPublish()).

mmlooloo
  • 18,937
  • 5
  • 45
  • 64
  • Thank you for your answer. now i know why it's not working properly. since the number of concurrent asynctasks is one, what would be a proper alternative to approach this? what if i implement the server socket creation to thread creation part, where i initially implement the async task execution? then remove the async task and make the Clientworker public. will that be fine? – senrulz Aug 04 '14 at 06:38
  • hey a quick question, how do i distinguish a receiving image and a string at the server end? i need two handlers for the two tasks if i'm correct, so how do i identify what i received is either string or an image? – senrulz Aug 04 '14 at 07:16
  • He will not be able to run second async task correctly, because port 8988 will be busy. – Vetalll Aug 04 '14 at 07:26
  • @Vetalll thanks for the reply, so if i use a different port like 8080 for string and 8988 for image should that be fine? – senrulz Aug 04 '14 at 07:36
  • I realy realy sorry for my mistake you can punish me and do not acssepting my answer and vote me down – mmlooloo Aug 04 '14 at 07:47
  • @mmlooloo oh it's fine! mistakes do happen. thank you for looking into it further and letting me know. really appreciate it. since i don't have two or more device with me right now, i'll check that and let you know asap how it goes and the function you mentioned is publishProgress (Progress... values) if i'm correct. thanks again! – senrulz Aug 04 '14 at 08:06
  • @mmlooloo hey, i added this `publishProgress(f.getAbsolutePath());` and how can return the `f.getAbsolutePath()` at the `onProgressUpdate(String... progress)` – senrulz Aug 04 '14 at 16:36
  • have not gotten result !! I have to go somewhere now and I 'll be back and definitely help you. (if i do not disturb you as today:-) – mmlooloo Aug 04 '14 at 16:39
  • @mmlooloo it's oki :) get back to me with an answer asap :) i really appreciate the help from you! – senrulz Aug 04 '14 at 17:21
  • How many client do you want to support? what do you want to do in onPostExecute()? please explain onPostExecute()? what is intended to be happened and after what event? – mmlooloo Aug 04 '14 at 19:22
  • @mmlooloo minimum of 4 or 5 clients needs to be supported. onPostExecute() is included in the coding as you can see. a quick explanation would be, i'm using this for wifi-direct communication. when all the clients are connected to the device running as server (Group Owner) clients should be able to send images to the server and server should display one after the other as images are received, in the screen – senrulz Aug 04 '14 at 19:31
  • @mmlooloo when a button is clicked. – senrulz Aug 04 '14 at 19:38
  • I provided my answer where to upload or mail ? – mmlooloo Aug 04 '14 at 19:40
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/58641/discussion-between-senrulz-and-mmlooloo). – senrulz Aug 04 '14 at 19:47