0

I'm trying to implement a client-server pair in Android using standard Java sockets. So far, I've successfully implemented one to one client-server connection. Now, I'm modifying my server side code to accept multiple client connection. I've taken help from here. I'm creating a serverSocket and wait for client connection in an infinite while loop. Once the client side socked is accepted, I run a new thread to handle that client and then again wait for new connection. Unfortunately, the program keeps crashing for some unknown reason! The logcat simply says- "error opening trace file: No such file or directory". The file path is correct (it was working fine in older implementation). Can anyone suggest what am I doing wrong? Is it related to missing manifest permission? Here is what I've done so far:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    
    Intent launchFileManager = new Intent(getBaseContext(),
            FileChooserActivity.class);
    startActivityForResult(launchFileManager, REQUEST_CODE); //receives files
    //fileArray has been populated here
    
    Button btn=(Button)findViewById(R.id.dispFilesid);
    btn.setOnClickListener(new View.OnClickListener() {
        
        @Override
        public void onClick(View v) {
            initializeServer();
        }
    });
}

private void initializeServer() {
    boolean listening = true;
    try {
        serversocket = new ServerSocket(4444);
    } catch (IOException e) {
        e.printStackTrace();
        Log.d("Listen failed", "Listening to port 4444 failed");
    }
    while (listening) {
        try {
            socket = serversocket.accept();
            Thread Clienttrd = new Thread(new Runnable() {
                @Override
                public void run() {
                    
                    try {
                        OutputStream myos=socket.getOutputStream();
                        myos.write(filepathNameArray.size()); //send file count
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    
                    if (!fileArray.isEmpty()) {
                        for (int i = 0; i < filepathNameArray.size(); i++){
                            copyFile(fileArray.get(i), fileArray.get(i).getName().toString());
                            //mtv.setText(fileArray.get(i).getName().toString());
                        }
                    }
                }
            });
            Clienttrd.start();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

The intent for FileChooserActivity returns an ArrayList containing a list of file URIs. These URIs are then wrapped around files and written over DataOutputStream of Socket object. Please help. Any insight would be appreciated! Thanks in advance!

2
  • You need to post stack trace and full error message (and tell us which line is causing the issue). Commented Apr 6, 2014 at 18:08
  • 1
    I don't know if this is causing your problem, but you have some issues with thread safety here. listening and fileArray are not thread safe, but are potentially accessed from multiple threads, which is a recipe for trouble. Commented Apr 6, 2014 at 18:13

1 Answer 1

1

Finally solved the problem. This might help others who land on this page in future. The problem: I was using the same thread for accepting and handling the client connection. So, the server could not become free for listening other incoming connections. I wrote a separate ConnectionHandler class for handling client connection:

btn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            Thread trd = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        serversocket = new ServerSocket(4444);
                    } catch (IOException e) {
                        e.printStackTrace();
                        Log.d("Listen failed",
                                "Listening to port 4444 failed");
                    }

                    while (listening) {
                        try {
                            socket = serversocket.accept();
                            Runnable connectionHandler = new ConnectionHandler(
                                    socket, fileArray, filepathNameArray);
                            new Thread(connectionHandler).start();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            });
            trd.start();
        }
    });

ConnectionHandler (This solved my issue):

    public class ConnectionHandler implements Runnable {

    private Socket socket=null;
    private ArrayList<File> fileArray=null;
    ArrayList<String> filepathNameArray=null;

    public ConnectionHandler(Socket socket, ArrayList<File> fileArray, ArrayList<String> filepathNameArray) {
        super();
        this.socket = socket;
        this.fileArray=fileArray;
        this.filepathNameArray=filepathNameArray;
    }
    @Override
    public void run() {
        try {
            OutputStream myos=socket.getOutputStream();
            myos.write(filepathNameArray.size()); //send file count
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        if (!fileArray.isEmpty()) {
            for (int i = 0; i < filepathNameArray.size(); i++){
                copyFile(fileArray.get(i), fileArray.get(i).getName().toString());
                //mtv.setText(fileArray.get(i).getName().toString());
            }
        }

    }
    private void copyFile(File file, String name) {
        FileInputStream fis;
        long filesize = file.length();
        try {
            fis = new FileInputStream(file);
            BufferedInputStream bis = new BufferedInputStream(fis);
            @SuppressWarnings("resource")
            DataInputStream dis = new DataInputStream(bis);
            byte[] mybytearray = new byte[16384];
            OutputStream os;
            if (socket != null) {
                os = socket.getOutputStream();
                DataOutputStream dos = new DataOutputStream(os);
                dos.writeUTF(name); // filename is also sent to client
                dos.writeLong(filesize); // file size is also sent to client
                long z = filesize;
                int n = 0;
                while ((z > 0)
                        && (n = dis.read(mybytearray, 0,
                                (int) Math.min(mybytearray.length, z))) != -1) {
                    dos.write(mybytearray, 0, n);
                    dos.flush();
                    z -= n;
                }
            }
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.