多个文件传输协议,使用"身份验证"从Android到Server

时间:2014-12-18 13:41:29

标签: java android network-protocols

我是一位寻求在Android上实施简单文件传输协议的新手程序员。

问题:

多部Android手机需要连接到服务器才能接收/发送保存在内部存储中的一系列XML文件。服务器需要知道哪个电话正在请求连接,以便它可以将文件保存在正确的文件夹中。

可能的解决方案/算法:

有关于如何将文件发送到服务器的各种教程/示例,但它们似乎都没有实现某种"身份验证"。

理想情况下,我想实现以下内容(我将使用隐喻):

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]

我意识到这很可能会提高效率,但我不知道从哪里开始...... 甚至可以在等待响应的同时启动与服务器的连接并进行多次交互吗?

问题: 有人能以某种方式把我推向正确的方向吗?我是编写自己的协议还是可以使用标准功能完成?这种实现的最佳/最简单的现有协议是什么?

我发现this article很有趣,但我不知道它如何用于带有身份验证的多个文件

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:2)

这比使用老式FTP更容易,我已成功用于从应用程序收集数据,您的服务器肯定会支持它。

  1. 使用enter link description here为每个Android设备获取唯一ID。您将获得一个64位数字(作为十六进制字符串),它是在每个设备首次启动时随机生成的。它应该在设备的使用寿命中保持不变。

  2. 导入Apache Commons FTP并使用the method describe here在服务器上的工作目录中创建一个名称与唯一ID匹配的目录名。

  3. 使用相同的库使用FTP上传文件。您将找到许多如何执行此操作的示例。它只需要很少的代码。

  4. 与您的聊天方案不同,这是一个非常客户端的解决方案,您可能不希望上传文件的手机 - 没有黑名单 - 但它很容易实现。

答案 1 :(得分:1)

对于那些对(可怕的)代码感兴趣以执行各种FTP功能的人来说,这对我有用。 它需要apache commons ftp jar文件,可以在互联网上找到。

//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) {
    }
}

我认为这可能会引起一些类似的问题。