android通过socket发送大文件到服务,并且在服务器接受完后返回一个结果给android。主要的是需要在android通过socket.getOutputStream()传送完文件后,需要关闭socket的OutputStream(socket.shutdownOutput();),而并不是执行getOutputStream()对象的close()方法,如果执行这个方法,那么socket就关闭了,就接收不到服务器返回的结果了。如果不关闭客户端的输出流,那么服务器端socket获取输入流对象后,调用这个对象的read方法会在执行完后一直处于等待状态,也就是read阻塞。socket输入流不同于文件输入流,一般调用in.read(),如果返回-1代表就结束了,但是socket这个输入流的read不会返回-1,(如果客户端在发送完文件后不及时关闭);
android端代码:
package com.roadview.drivermate.net;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import android.util.Log;
import com.roadview.drivermate.common.AppConst;
public class SocketService {
String tag = "SocketService";
File file=null;
String sendinfo=null;
//socket执行结果
public int status;
public SocketService() {
super();
}
public SocketService(File file, String sendinfo) {
super();
this.file = file;
this.sendinfo = sendinfo;
}
/**
* 上传文件方法(图片,视频,录音)
* @param file 文件对象
* @param sendinfo 文件信息
* @return
*/
public String sendSocket() {
String result = null;
FileInputStream reader = null;
DataOutputStream out = null;
DataInputStream in = null;
Socket socket = new Socket();
byte[] buf = null;
try {
// 连接Socket
socket.connect(new InetSocketAddress(AppConst.ADDRESS,
AppConst.PORT), 1000);
// 1. 读取文件输入流
reader = new FileInputStream(file);
// 2. 将文件内容写到Socket的输出流中
out = new DataOutputStream(socket.getOutputStream());
out.writeInt(AppConst.UPLOAD);
out.writeUTF(sendinfo);
int bufferSize = 20480; // 20K
buf = new byte[bufferSize];
int read = 0;
// 将文件输入流 循环 读入 Socket的输出流中
while ((read = reader.read(buf, 0, buf.length)) != -1) {
out.write(buf, 0, read);
}
Log.i(tag, "socket执行完成");
out.flush();
// 一定要加上这句,否则收不到来自服务器端的消息返回
socket.shutdownOutput();
// //获取服务器端的相应
in = new DataInputStream(socket.getInputStream());
status = in.readInt();
result = in.readUTF();
Log.i(tag, "返回结果:" + status + "," + result);
} catch (Exception e) {
Log.i(tag, "socket执行异常:" + e.toString());
} finally {
try {
// 结束对象
buf = null;
out.close();
in.close();
reader.close();
socket.close();
} catch (Exception e) {
}
}
return result;
}
}
服务器端代码1:
package audioTest;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
/**
*
* 该类是Socket服务端的入口
*/
public class Server extends Thread{
// 端口
public static int port = 9999;
private static ServerSocket server = null;
// 存放录音文件的 文件夹
private final String AUDIO_RECORD = "D:\\audio_record";
public void run() {
if(server == null){
try{
//1、新建ServerSocket实例
server = new ServerSocket(port);
}catch(IOException e){
e.printStackTrace();
}
}
System.out.println(new Date().toString() + " \n 服务器启动...");
while(true){
try{
//2、访问ServerSocket实例的accept方法取得一个客户端Socket对象
Socket client = server.accept();
if(client == null || client.isClosed()) continue;
// 判断客户端请求类型
DataInputStream in = new DataInputStream(new BufferedInputStream(client.getInputStream()));
switch (in.readInt()) {
// 上传文件
case 1:
new SocketUpLoad(client, AUDIO_RECORD).start();
break;
// 下载文件
case 2:
new SocketDownLoad(client, AUDIO_RECORD).start();
break;
default:
break;
}
}catch(IOException ex){
ex.printStackTrace();
}
}
}
public static void main(String[] args) {
new Server().start();
}
}
服务器端代码2:
package com.roadview.drivermate.socket.service;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Date;
public class SocketUpLoad extends Thread {
// socket对象
private Socket client;
// 保存路径
private String savepath=AppConst.WEBROOT+AppConst.WEBDIR+"\\";
//返回路径(相对路径)
private String filepath="/"+AppConst.WEBDIR+"/";
public SocketUpLoad(Socket client) {
this.client = client;
}
// 创建目录(不存在则创建)
public File CreateDir(String dir) {
File file = new File(dir);
if (!file.exists()) {
file.mkdirs();
}
return file;
}
public void run() {
if (client == null)
return;
DataInputStream in = null;
BufferedOutputStream fo = null;
DataOutputStream out = null;
try {
// 1、访问Socket对象的getInputStream方法取得客户端发送过来的数据流
in = new DataInputStream(new BufferedInputStream(
client.getInputStream()));
String[] str = in.readUTF().split("\\|");
//文件名
String fileName =System.currentTimeMillis()+"."+ str[0].split("\\.")[1]; // 取得附带的文件名
System.out.println(new Date().toString() + " \n 文件名为:"
+ fileName);
String filetype=str[1];
String userid = str[2];// 取用户ID
//存储路径
savepath=savepath+filetype+"\\"+userid;
if (savepath.endsWith("/") == false
&& savepath.endsWith("\\") == false) {
savepath += "\\";
}
System.out.println("保存路径:"+savepath);
//创建目录
CreateDir(savepath);
//返回文件名和路径
filepath = filepath+filetype+"/"+userid+"/"+fileName;
System.out.println("返回路径:"+filepath);
// 2、将数据流写到文件中
fo = new BufferedOutputStream(new FileOutputStream(new File(
savepath+"\\"+fileName)));
int bytesRead = 0;
byte[] buffer = new byte[1024];
while ((bytesRead = in.read(buffer, 0, buffer.length)) != -1) {
fo.write(buffer, 0, bytesRead);
}
fo.flush();
fo.close();
System.out.println(new Date().toString() + " \n 数据接收完毕");
// 3、获得Socket的输出流,返回一个值给客户端
out = new DataOutputStream(new BufferedOutputStream(
client.getOutputStream()));
out.writeInt(1);
out.writeUTF(filepath);
out.flush();
} catch (Exception ex) {
ex.printStackTrace();
try {
out.writeInt(0);
out.flush();
} catch (IOException e) {
System.out.println(new Date().toString() + ":" + e.toString());
}
} finally {
try {
out.close();
fo.close();
in.close();
client.close();
} catch (IOException e) {
System.out.println(new Date().toString() + ":" + e.toString());
}
}
}
}