原文链接:点击打开链接
java中Socket实现文件传输学习记录
服务端FileTransferServer:
package com.zhuguozhu.server;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.RoundingMode;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.DecimalFormat;
/**
* 文件传输服务端代码FileTransferServer
* @author Guozhu Zhu
* @date 2018/5/10
* @version 1.0
*
*/
public class FileTransferServer extends ServerSocket {
private static final int SERVER_PORT = 8899;
private static DecimalFormat df = null;
static {
//设置数字格式,保留一位有效小数
df = new DecimalFormat("#0.0");
df.setRoundingMode(RoundingMode.HALF_UP);
df.setMinimumFractionDigits(1);
df.setMaximumFractionDigits(1);
}
public FileTransferServer() throws IOException {
super(SERVER_PORT);
}
/**
* 使用线程处理每个客户端传输的文件
*/
public void load() throws IOException {
while (true) {
//server尝试接收其他Socket的连接请求,server的accept方法是阻塞的
Socket socket = this.accept();
/*
* 我们的服务端请求处理客户端的连接请求是同步的,每次接收到来自客户端的连接请求后,
* 都要先跟当前的客户端通信完之后才能再进一步处理下一个连接请求。
* 这在并发比较多的情况下会产生严重影响程序的性能
* 为此,我们可以把它改为如下这种异步处理与客户端通信的方式
* 每次接收到一个Socket就创建一个新的线程来处理它
*/
new Thread(new Task(socket)).start();
}
}
class Task implements Runnable{
private Socket socket;
private DataInputStream dis;
private FileOutputStream fos;
public Task(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
dis = new DataInputStream(socket.getInputStream());
//文件名和长度
String fileName = dis.readUTF();
long fileLength = dis.readLong();
File directory = new File("D:/");
if (!directory.exists()) {
directory.mkdir();
}
File file = new File(directory.getAbsolutePath() + File.separatorChar + fileName);
fos = new FileOutputStream(file);
//开始接收文件
byte[] bytes = new byte[1024];
int length = 0;
while ( (length = dis.read(bytes, 0, bytes.length)) != -1) {
fos.write(bytes, 0, length);
fos.flush();
}
System.out.println("==文件接收成功[File Name: " + fileName + "] [Size: " + getFormatFileSize(fileLength) + " ]==");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
if (dis != null) {
dis.close();
}
socket.close();
} catch(Exception e) {
}
}
}
}
/**
* 格式化文件大小
* @param length
* @return
*/
private String getFormatFileSize(long length) {
double size = ((double) length) / (1 << 30);
if (size >= 1) {
return df.format(size) + "GB";
}
size = ((double) length) / (1 << 20);
if (size >= 1) {
return df.format(size) + "MB";
}
size = ((double) length) / (1 << 10);
if (size >= 1) {
return df.format(size) + "KB";
}
return length + "B";
}
public static void main(String[] args) throws IOException {
FileTransferServer server = new FileTransferServer(); //启动服务端
try {
server.load();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
客户端FileTransferClient:
package com.zhuguozhu.client;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 文件传输客户端FileTransferClient
* @author Guozhu Zhu
* @date 2018/5/10
* @version 1.0
*
*/
public class FileTransferClient extends Socket{
private static final String SERVER_IP = "127.0.0.1"; //服务端ip
private static final int SERVER_PORT = 8899; //服务端的端口
private Socket socket;
private FileInputStream fis;
private DataOutputStream dos;
public FileTransferClient() throws UnknownHostException, IOException {
super(SERVER_IP, SERVER_PORT);
this.socket = this;
System.out.println("Client[port:" + socket.getLocalPort() + "] 成功连接服务端");
}
public void sendFile() throws Exception {
try {
File file = new File("G:/好的学习链接.docx");
if (file.exists()) {
fis = new FileInputStream(file);
dos = new DataOutputStream(socket.getOutputStream());
//文件名和长度
dos.writeUTF(file.getName());
dos.flush();
dos.writeLong(file.length());
dos.flush();
//开始传输文件
System.out.println("==开始传输文件==");
byte[] bytes = new byte[1024];
int length = 0;
int progress = 0;
while ( (length = fis.read(bytes, 0, bytes.length)) != -1) {
dos.write(bytes, 0, length);
dos.flush();
progress += length;
System.out.println("|" + (100*progress/file.length()) + "%");
}
System.out.println("==文件传输成功==");
}
}catch (Exception e) {
} finally {
if (fis != null) {
fis.close();
}
if (dos != null) {
dos.close();
}
socket.close();
}
}
public static void main(String[] args) {
try {
FileTransferClient client = new FileTransferClient(); //客户端启动
client.sendFile(); //传输文件
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //传输文件
}
}