java两台服务器之间,大文件上传(续传),采用了Socket通信机制以及JavaIO流两个技术点,具体思路如下:
实现思路:
1、服:利用ServerSocket搭建服务器,开启相应端口,进行长连接操作
2、服:使用ServerSocket.accept()方法进行阻塞,接收客户端请求
3、服:每接收到一个Socket就建立一个新的线程来处理它
4、客:利用Socket进行远程连接,询问已上传进度
5、客:使用FileInputStream.skip(long length)从指定位置读取文件,向服务器发送文件流
6、服:接收客户端输入流,使用RandomAccessFile.seek(long length)随机读取,将游标移动到指定位置进行读写
7、客/服:一个循环输出,一个循环读取写入
8、示例:以下是具体代码,仅供参考
文件介绍:
FileUpLoadServer.java(服务器接收文件类)
FileUpLoadClient.java(客户端发送文件类)
FinalVariables.java(自定义参数类)
SocketServerListener.java(JavaWeb启动Socket操作类)
web.xml(配置文件,跟随项目启动)
断点上传(服务端)
package com.cn.csdn.seesun2012.socket;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.math.RoundingMode;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.DecimalFormat;
public class FileUpLoadServer extends ServerSocket {
// 文件大小
private static DecimalFormat df = null;
// 退出标识
private boolean quit = false;
static {
// 设置数字格式,保留一位有效小数
df = new DecimalFormat("#0.0");
df.setRoundingMode(RoundingMode.HALF_UP);
df.setMinimumFractionDigits(1);
df.setMaximumFractionDigits(1);
}
public FileUpLoadServer(int report) throws IOException {
super(report);
}
/**
* 使用线程处理每个客户端传输的文件
*
* @throws Exception
*/
public void load() throws Exception {
System.out.println("【文件上传】服务器:" + this.getInetAddress() + " 正在运行中...");
while (!quit) {
// server尝试接收其他Socket的连接请求,server的accept方法是阻塞式的
Socket socket = this.accept();
/**
* 我们的服务端处理客户端的连接请求是同步进行的, 每次接收到来自客户端的连接请求后,
* 都要先跟当前的客户端通信完之后才能再处理下一个连接请求。 这在并发比较多的情况下会严重影响程序的性能,
* 为此,我们可以把它改为如下这种异步处理与客户端通信的方式
*/
// 收到请求,验证合法性
String ip = socket.getInetAddress().toString();
ip = ip.substring(1, ip.length());
System.out.println("服务器接收到请求,正在开启验证对方合法性IP:" + ip + "!");
// 每接收到一个Socket就建立一个新的线程来处理它
new Thread(new Task(socket, ip)).start();
}
}
/**
* 处理客户端传输过来的文件线程类
*/
class Task implements Runnable {
private Socket sk;// 当前连接
private String ips; // 当前连接IP址
public Task(Socket socket, String ip) {
this.sk = socket;
this.ips = ip;
}
public void run() {
Socket socket = sk;// 重新定义,请不要移出run()方法外部,否则连接两会被重置
String ip = ips;// 重新定义,同上IP会变
long serverLength = -1l;// 定义:存放在服务器里的文件长度,默认没有为-1
char pathChar = File.separatorChar;// 获取:系统路径分隔符
String panFu = "D:&