简体   繁体   中英

Multiple files transfer protocol with “authentication” from Android to Server

I'm a newbie programmer looking for a way to implement a simple file transfer protocol on Android.

Problem:

Several Android phones need to connect to a server to receive/send a series of XML files saved in internal storage. The server needs to know which phone is requesting a connection so that it can save the files in the correct folder.

Possible solution/algorithm:

There are various tutorials/examples on how to send a file to a server, but none of them seem to implement some kind of "authentication".

Ideally I would like to implement the following (I'll use a metaphor):

Phone: Hello. 

Server: Hi. Who are you and what do you want? [send/receive]

Phone A: I'm phone A and I would like to send files.

Server: How many files do you want to send, Phone A?

Phone A: 6 files, [+extra data like total size or whatever]

Server: Alright, you can begin the transfer.

Phone A: Transfers...

Server: I've succesfully received 6 files, have a good day. [stores the files in a PhoneA folder]

Phone A: Bye! [closes connection]

I realise this could very likely be made a lot more efficient, but I don't know where to begin... Is it even possible to initiate a connection with a server and interact multiple times while waiting for responses?

Question : Could anyone push me in the right direction somehow? Do I write my own protocol or can this be done with standard functionality? What are the best/easiest existing protocols for this kind of implementation?

I've found this article interesting but I don't see how it could be used for multiple files with authentication

Any help would be much appreciated!

This is easier than you think using old-school FTP, which I've used with success in collecting data from apps, and your server will surely support it.

  1. Get a unique ID for each Android device using enter link description here . You get a 64-bit number (as a hex string) that is randomly generated on each device's first boot. It's supposedly constant for the life of the device.

  2. Import Apache Commons FTP and use the method describe here to create a directory name inside your working directory on the server with a name matching the unique id.

  3. Use the same library to upload the files using FTP. You'll find many example of how to do this. It takes very minimal code.

Unlike your chat scenario, this is a very client-side solution, and phones you might not want to could upload files -- there's no blacklist -- but it's easy to implement.

For those interested in (terrible) code to perform various FTP functions, here's what worked for me. It requires the apache commons ftp jar file which can be found on the internet.

//Button that starts it all
public void updateWorkordersList(View view) {

    if (!CheckNetworkConnection.isOnline()) {

        SharedPreferences prefs = PreferenceManager
                .getDefaultSharedPreferences(this);
        String connectionString = prefs
                .getString("connection_string", null);
        String userName = prefs.getString("FTPusername", null);

        DownloadFilesTask task = new DownloadFilesTask(connectionString,
                userName);
        task.execute();

        Fragment frg = null;
        frg = getFragmentManager()
                .findFragmentByTag("buttonsContainer");
        final FragmentTransaction ft = getFragmentManager()
                .beginTransaction();
        ft.detach(frg);
        ft.attach(frg);
        ft.commit();

    }
}

private class DownloadFilesTask extends AsyncTask<Void, Void, Boolean> {
    private FTPClient mFtpClient = new FTPClient();
    private FTPFile[] mFileArray;
    private String _address;
    private String _user;
    private String _pass;

    public DownloadFilesTask(String ip, String user) {
        _address = ip;
        _user = user;

    }

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

        try {
            mFtpClient.setConnectTimeout(10 * 1000);
            mFtpClient.connect(InetAddress.getByName("insert server here"));
            boolean status = mFtpClient.login("username", "password");
            if (FTPReply.isPositiveCompletion(mFtpClient.getReplyCode())) {
                mFtpClient.setFileType(FTP.ASCII_FILE_TYPE);
                mFtpClient.enterLocalPassiveMode();
                mFileArray = mFtpClient.listFiles();
            }
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //Download All Files
        if (FTPReply.isPositiveCompletion(mFtpClient.getReplyCode())) {
            File directory = null;
            directory = new File(Environment.getExternalStoragePublicDirectory(
                    Environment.DIRECTORY_DOWNLOADS).getPath());

            for (FTPFile file : mFileArray) {

                OutputStream outputStream = null;
                try {
                    outputStream = new BufferedOutputStream(
                            new FileOutputStream(directory + "/"
                                    + file.getName()));
                    mFtpClient.setFileType(FTP.BINARY_FILE_TYPE);
                    mFtpClient.retrieveFile(file.getName(), outputStream);
                } catch (Exception ex) {
                    ex.printStackTrace();
                } finally {
                    if (outputStream != null) {
                        try {
                            outputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }

        }

        //Upload All Files
        if (FTPReply.isPositiveCompletion(mFtpClient.getReplyCode())) {
            File directory = null;
            directory = new File(Environment.getExternalStoragePublicDirectory(
                    Environment.DIRECTORY_DOWNLOADS).getPath() + "/srvReady");


            for (File file : directory.listFiles()) {
                   try {  
                        FileInputStream srcFileStream = new FileInputStream(directory + "/" + file.getName());  
                        boolean status = mFtpClient.storeFile(_user + "/" + file.getName(),  
                                  srcFileStream);    
                        srcFileStream.close(); 
                        if (status){
                            file.delete();
                        }
                   } catch (Exception e) {  
                        e.printStackTrace();  
                   }                       
            }               
        }

        try {
            mFtpClient.logout();
            mFtpClient.disconnect();
        } catch (Exception e) {
            // TODO: handle exception
        }

        return true;
    }

    protected void onProgressUpdate(Integer... progress) {
    }

    protected void onPostExecute(Boolean result) {
    }
}

I figure this could be of some use might someone ever come across a similar problem.

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