我是一个新手程序员,正在寻找一种在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]
我意识到这很可能会提高效率,但我不知道从哪里开始......是否可以启动与服务器的连接并在等待响应时多次交互?
问题:谁能以某种方式将我推向正确的方向?我应该编写自己的协议,还是可以使用标准功能来完成?对于这种实现,最好/最简单的现有协议是什么?
我发现这篇文章很有趣,但我看不出它如何用于具有身份验证的多个文件
任何帮助将不胜感激!
这比您使用老式FTP更容易,我已经成功地使用了从应用程序中收集数据,并且您的服务器肯定会支持它。
-
使用在此处输入链接说明获取每个 Android 设备的唯一 ID。您将获得一个 64 位数字(作为十六进制字符串(,该数字在每个设备首次启动时随机生成。据说它在设备的使用寿命内是恒定的。
-
导入Apache Commons FTP并使用此处描述的方法在服务器上的工作目录中创建一个目录名称,其名称与唯一ID匹配。
-
使用相同的库通过 FTP 上传文件。您会找到许多如何执行此操作的示例。它需要非常少的代码。
与您的聊天场景不同,这是一个非常客户端的解决方案,您可能不想上传的手机可以上传文件 - 没有黑名单 - 但它很容易实现。
对于那些对执行各种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) {
}
}
我认为如果有人遇到类似的问题,这可能会有所用处。