一,简介
通过socket的tcp/ip协议,发送文件
二,原理
发送端:发送文件,先发送文件类型和文件名字---再进行发送文件
接收端:先判断是否是文件传输,是就进行文件名的获取-----并创建文件,把文件流逐一写入文件。
三,代码
发送端
/**
* 发送文件
*/
@OnClick(R.id.sendfile)
public void sendFile(){
final String path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/ab.doc";
send_str = new File(path).getName();
if (!send_str.isEmpty()){
Chat chat = new Chat();
chat.setId(1);
chat.setTalk(send_str);
chat.setFiletype(getString(R.string.file));
chats.add(chat);
chatAdapter.notifyDataSetChanged();
//自动滑到最底端
mRecycle.scrollToPosition(chatAdapter.getItemCount()-1);
Thread thread = new Thread(){
@Override
public void run() {
super.run();
try {
sockets = new Socket(ip_diu,8000);
outputStream = sockets.getOutputStream();
byte[] buffer = TalkUtil.CreateJson(getString(R.string.file) , send_str);
outputStream.write(buffer);
SendFileUtil.sendFiel(sockets , outputStream , path);
} catch (IOException e) {
e.printStackTrace();
}
}
};
thread.start();
}else {
Toast.makeText(this,R.string.send_select , Toast.LENGTH_SHORT).show();
}
}
/**
* 发送文件
* @param path 文件地址
*/
public static void sendFiel(Socket s , OutputStream out, String path) {
try {
FileInputStream inputStream = new FileInputStream(new File(path));
byte[] buf = new byte[1024];
int len;
//判断是否读到文件末尾
while ((len = inputStream.read(buf)) != -1) {
out.write(buf, 0, len);//将文件循环写入输出流
}
//告诉服务端,文件已传输完毕
s.shutdownOutput();
//获取从服务端反馈的信息
/*BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
String serverBack = in.readLine();
Log.d("TAG", serverBack);*/
//资源关闭
s.close();
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
接收端
/*
服务器端接收数据
需要注意以下一点:
服务器端应该是多线程的,因为一个服务器可能会有多个客户端连接在服务器上;
*/
private void receiveData() {
Thread thread = new Thread(){
@Override
public void run() {
super.run();
/*
指明端口号
*/
try {
serverSocket = new ServerSocket(8000);
}catch (IOException e){
e.printStackTrace();
}
/*
循环启动服务
*/
boolean b = true;
while (b){
Socket socket = null;
try {
if (!serverSocket.isClosed()){
socket = serverSocket.accept();
inputStream = socket.getInputStream();
new ServerThread(socket,inputStream).start();
}else {
b = false;
socket.close();
return;
}
}catch (Exception e){
e.printStackTrace();
}
}
}
};
thread.start();
}
class ServerThread extends Thread{
private Socket socket;
private InputStream inputStream;
public ServerThread(Socket socket,InputStream inputStream){
this.socket = socket;
this.inputStream = inputStream;
}
@Override
public void run() {
try {
int len = getxmlLeng(inputStream);
byte[] buffer = toByteArraytolong(inputStream , len);
String json_str = new String(buffer, "UTF-8");
try {
JSONObject jsonObject = new JSONObject(json_str);
String type = jsonObject.getString(Constant.type_key);
if (type.equals(getString(R.string.file))){
String filename = jsonObject.getString(Constant.talk_key);
AcceptFileUtil.receiveFile(getContext() , filename , inputStream );
}
Intent intent = new Intent(Constant.BROAD_REVICE);
intent.putExtra("msg",json_str);
sendBroadcast(intent);
}catch (JSONException e){
e.printStackTrace();
}
//当这个异常发生时,说明客户端那边的连接已经断开
} catch (IOException e) {
e.printStackTrace();
try {
inputStream.close();
socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
/**将输入流转化成byte[]的方法
* */
public static byte[] toByteArraytolong(InputStream input , int len) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int n = 0;
while ((n = input.read(buffer, 0, buffer.length)) != -1) {
output.write(buffer, 0, n);
int leng = output.toByteArray().length;
if ( leng >= len){
break;
}
}
return output.toByteArray();
}
/**
* 包头解析
*/
private static int getxmlLeng(InputStream in)throws IOException{
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[4];
int n = in.read(buffer);
output.write(buffer, 0, n);
byte[] b = output.toByteArray();
int len = b[0] & 0xFF |
(b[1] & 0xFF) << 8 |
(b[2] & 0xFF) << 16 |
(b[3] & 0xFF) << 24;
return len;
}
/**in
* 接收文件
* FileName 文件名字
*/
public static synchronized void receiveFile(Context context , String FileName ,InputStream in ) {
boolean b = true;
try {
while (b) {
//创建一个文件,指定保存路径和刚才传输过来的文件名
OutputStream saveFile = new FileOutputStream(
new File(context.getExternalCacheDir(), FileName));
byte[] buf = new byte[1024];
int len;
//判断是否读到文件末尾
while ((len = in.read(buf)) != -1) {
saveFile.write(buf, 0, len);
}
saveFile.flush();
saveFile.close();
//告诉发送端我已经接收完毕
/*OutputStream outputStream = socket.getOutputStream();
outputStream.write("文件接收成功".getBytes());
outputStream.flush();
outputStream.close();
socket.close();*/
b = false;
}
} catch (Exception e) {
e.printStackTrace();
}
}