简体   繁体   中英

How to accept multiple socket connection at Java server

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!

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();
        }
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM