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;
publicclass FileUpLoadServer extends ServerSocket {
// 文件大小
privatestatic DecimalFormat df =null;
// 退出标识
privateboolean 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
*/
publicvoid 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;
}
publicvoid run(){
Socket socket = sk;// 重新定义,请不要移出run()方法外部,否则连接两会被重置
String ip = ips; // 重新定义,同上IP会变
long serverLength =-1l;// 定义:存放在服务器里的文件长度,默认没有为-1
char pathChar = File.separatorChar; // 获取:系统路径分隔符
String panFu ="D:"; // 路径:存储文件盘符
DataInputStream dis =null; // 获取:客户端输出流
DataOutputStream dos =null;// 发送:向客户端输入流
FileOutputStream fos =null;// 读取:服务器本地文件流
RandomAccessFile rantmpfile =null; // 操作类:随机读取
try{
// 获取
dis =new DataInputStream(socket.getInputStream());
// 发送
dos =new DataOutputStream(socket.getOutputStream());
// 定义客户端传过来的文件名
String fileName ="";
while(fileName ==""){
// 读取客户端传来的数据
fileName = dis