【发布时间】:2016-10-06 03:43:25
【问题描述】:
我正在制作一个应该通过 wifi 直接连接发送和接收一些 json 文件的 android 应用程序(每当连接另一个设备时,它们都会交换所有 json 文件)。 这个问题主要是关于什么是最佳实践,因为我对android和java都很陌生。 当建立 wifi 直接连接时,两个设备(组所有者)之一成为服务器并打开服务器套接字;另一个连接到所述套接字并将一个 json 文件发送到服务器。
我希望客户端发送他所有的 json 文件,然后从服务器接收所有 json 文件,我想知道应该怎么做:我如何告诉一个文件结束了?我应该提前发送文件的长度,还是让客户端等待服务器完成读取的确认? 我可以发出“数据结束”信号(通过关闭 OutputStream 吗?)以停止接收端的读取循环,然后开始发送另一个文件?
为了了解一些上下文,这是我目前正在使用的代码:
客户端
@Override
protected String doInBackground(Void... params) {
Socket socket = new Socket();
try {
Log.d(TAG, "Opening client socket - ");
socket.bind(null);
socket.connect((new InetSocketAddress(mHost, Constants.PORT)), SOCKET_TIMEOUT);
Log.d(TAG, "Client socket - " + socket.isConnected());
OutputStream stream = socket.getOutputStream();
//There is only one file, so the loop here runs only once
File dir = Utils.graffitiDir(context);
for (File tmp : dir.listFiles()) {
FileInputStream in = new FileInputStream(tmp);
Utils.copyFileInOut(in, stream);
}
Log.d(TAG, "Client: Data written");
return "ok";
} catch (IOException e) {
Log.e(TAG, e.getMessage());
return null;
}
finally {
if (socket != null) {
if (socket.isConnected()) {
try {
socket.close();
} catch (IOException e) {
// Give up
e.printStackTrace();
}
}
}
}
}
服务器端
@Override
protected String doInBackground(Void... params) {
try {
ServerSocket serverSocket = new ServerSocket(Constants.PORT);
byte buf[] = new byte[4];
String res;
Log.d(TAG, "Server: Socket opened");
Socket client = serverSocket.accept();
Log.d(TAG, "Server: connection done");
File f = new File(context.getFilesDir(), Constants.DIRECTORY);
File dirs = new File(f.getParent());
if (!dirs.exists())
dirs.mkdirs();
f.createNewFile();
File newf = new File(f, Calendar.getInstance().getTime().toString());
Log.d(TAG, "server: copying files " + f.toString());
InputStream inputstream = client.getInputStream();
//copyFile(inputstream);
Utils.copyFileInOut(inputstream, new FileOutputStream(newf));
serverSocket.close();
return newf.getAbsolutePath();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
return null;
}
}
copyFileInOut 函数:
public static boolean copyFileInOut(InputStream inputStream, OutputStream out) {
byte buf[] = new byte[1024];
int len;
long startTime=System.currentTimeMillis();
try {
while ((len = inputStream.read(buf)) != -1) {
out.write(buf, 0, len);
Log.d("copyfile", "I'm writing");
}
out.close();
inputStream.close();
long endTime=System.currentTimeMillis()-startTime;
Log.d("copyfile", "Time taken to transfer all bytes is : " + endTime);
} catch (IOException e) {
Log.d(TAG, e.toString());
return false;
}
return true;
}
作为旁注,我看到了几个类似的问题 (Sending and receiving files on socket),其中的答案建议提前发送文件的长度,但我觉得我的情况有点不同,我没有有必要的经验来找出最佳解决方案。如果这是一个显而易见的问题,我深表歉意,但我自己找不到答案。
【问题讨论】: