前言
- 现接到一功能要求,Android 端实现在 WIFI 局域网的条件下和 PC 端通信;
- 经过调研,我了解到 Socket、TCP 等关键词;这里强调:沟通的重要性!
- 一开始我是蒙圈的,后来经过调研发现 PC 端是通过成熟的 MFC 框架写的,虽说也是 C,但实际细节,不去采坑是很难发现和理解的,这里强调实战的重要性!, 看再多书,不去实际操作都是花架子,空壳子。
PC 端
- 发送文件前,发送 待发送文件的信息 这里注意要求和其他同事沟通协议,毕竟人家的 C 代码你看不见,人家也不改……我这里的协议是
MD5$fileName$fileSize
;MD5 我用的是对文件进行加密,电脑端则是随机生成 @#%&*()_(*&……%$ - 接收端对发送的信息进行校验,如果文件存在就 返回 “YES”;
- 发送端对其发挥信息验证,如果是 “YES” 不必发送;
- 由于 PC 端是现成的,且是领导写的,不方(rang)便修改;所以一切都遵守 PC 端协议,迁就 MFC 代码;
Android 端
- 选择文件进行发送;
- 发送文件,一定 要开启线程进行!
- 遵守协议,对文件加密获取 32 为 MD5 码;获取文件名以及文件文件大小,按格式发送给 PC 端;代码如下:采坑狂魔已经把以下方法都试了,方法三可行。
//自行 try - catch 以及 close 操作,以下知识核心代码 Socket name = new Socket(ipAddress, port); for (int i = 0; i < fileName.size(); i++) { String tempPath = path.get(i).replaceAll(regEx, ""); File file = new File(tempPath); //注:MD5FileUtils 是对文件加密;如有需要请联系我 String MD5 = MD5FileUtils.md5(file); String confirmStr = MD5 + "$" + fileName.get(i) + "$" + file.length(); //方法一:PC闪退,且PC socket关闭 //OutputStream outputName = name.getOutputStream(); //OutputStreamWriter outputWriter = new OutputStreamWriter(outputName); //BufferedWriter bwName = new BufferedWriter(outputWriter); //bwName.write(confirmStr); //bwName.flush(); //bwName.close(); //outputWriter.close(); //outputName.close(); //方法二: //PrintWriter out = new PrintWriter(name.getOutputStream(),true); //out.print(confirmStr); //方式三:可行 OutputStream nameOPS = name.getOutputStream(); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(nameOPS, "GBK"); outputStreamWriter.write(confirmStr); outputStreamWriter.flush(); //这里不可以关闭 socket ;也不必关闭流,将其置为 null 即可;否则 PC 端闪退! nameOPS = null; ``` 3. 不对发送端是否返回 "YES" 进行判断; 4. 发送文件数据;以下是核心代码 ```java //TODO:发送文件内容 OutputStream outputData = name.getOutputStream(); FileInputStream fileInput = new FileInputStream(tempPath); //判断是否读到文件末尾 int size = 0; long receivedSize = 0L; byte[] buffer = new byte[1024]; while (true) { size = fileInput.read(buffer); if (size == -1) { Log.i(TAG, "SendFile: While : receivedSize = " + receivedSize + " file.length() = " + file.length()); break; } outputData.write(buffer, 0, size); outputData.flush(); receivedSize += size; if (!(receivedSize < file.length())) { Log.i(TAG, "SendFile: While : receivedSize = " + receivedSize + " file.length() = " + file.length()); break; } } //同样,该置为 null 的置为 null ;不该 close 的不要 close; outputData = null; fileInput = null; ```
问题:
在传输多个文件时出现以下几个问题;
broken pipe
connect reset