发送方
import java.io.*;
import java.net.*;
import java.util.Arrays;
import java.util.Random;
import java.util.logging.Logger;
public class SendFile{
private Logger log = Logger.getLogger("SendFile");
/**
* 接收方地址
*/
private String address = "127.0.0.1";
/**
* 接收方端口
*/
private String port = "10086";
/**
* 发送的文件地址
*/
private String fileName = null;
/**
* 发送文件的缓冲区大小
*/
private static final int SEND_SIZE = 1024;
/**
* 文件结束符长度
*/
private static int FILE_END_SIZE = 100;
/**
* 入口函数
* @param args args[0]: 文件位置. args[1]: ip 地址(默认:127.0.0.1)。 args[2]:端口号(默认:10086)
*/
public static void main(String[] args) {
if(args.length <= 0) {
System.out.println("需要参数 文件位置。");
System.exit(0);
}
SendFile sendFile = new SendFile();
sendFile.fileName = args[0];
if(args.length == 1){
sendFile.log.warning("使用默认 ip 地址");
}else{
sendFile.address = args[1];
sendFile.log.info("使用 IP 地址:"+args[1]);
}
if(args.length > 2)sendFile.port = args[2];
sendFile.log.info("使用端口号:"+sendFile.port);
sendFile.start();
}
public SendFile(String address){
this.address = address;
}
public SendFile(String address,String fileName){
this.address = address;
this.fileName = fileName;
}
public SendFile(String address,String port,String fileName){
this.address = address;
this.port = port;
this.fileName = fileName;
}
public SendFile(){}
public void start(){
if(fileName==null||fileName.equals("")){
log.severe("文件名不能为空");
}
if(address==null||address.equals("")){
log.severe("ip 不能为空");
}
File file = new File(fileName);
FileInputStream fileInputStream = null;
//创建数据缓冲区
byte [] sendBytes = new byte[SEND_SIZE];
int len = SEND_SIZE;
//建立UDP连接
DatagramSocket datagramSocket = null;
DatagramPacket p = null;
try {
long st = System.currentTimeMillis();
fileInputStream = new FileInputStream(file);
datagramSocket = new DatagramSocket();
byte[] fileEndBytes = buildFileEnd(FILE_END_SIZE,getLastFileName());
//System.out.println(getLastFileName());
p = new DatagramPacket(fileEndBytes,FILE_END_SIZE,InetAddress.getByName(address),Integer.parseInt(port));
//发送文件结束符
log.info("发送文件结束符,长度:"+FILE_END_SIZE);
datagramSocket.send(p);
log.info("发送文件结束符成功");
//发送数据
while((len = fileInputStream.read(sendBytes,0,len)) != -1){
p.setData(sendBytes,0,len);
datagramSocket.send(p);
log.info("发送数据包成功,长度:"+len+" byte");
}
//再次发送文件结束符
log.info("再次发送文件结束符,长度:"+FILE_END_SIZE);
p.setData(fileEndBytes,0,FILE_END_SIZE);
datagramSocket.send(p);
log.info("文件发送完毕,用时:"+((System.currentTimeMillis()-st)/1024)+" s");
} catch (UnknownHostException e) {
log.severe("ip 地址创建失败,错误信息:"+e.getMessage());
} catch (FileNotFoundException e) {
log.severe("文件打开失败,错误信息:"+e.getMessage());
} catch (IOException e) {
log.severe("文件信息读取失败,错误信息:"+e.getMessage());
} finally {
try {
if(fileInputStream!=null)fileInputStream.close();
if(datagramSocket!=null)datagramSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/** 创建文件结束符
* @param length 长度
* @param nameFile 加入文件名称
* @return
*/
private byte[] buildFileEnd(int length,String nameFile){
if(length>SEND_SIZE)length = SEND_SIZE;
byte[] bytes = new byte[length];
Random random = new Random(System.currentTimeMillis());
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) random.nextInt(120+1);
}
byte[] bytes1 = nameFile.getBytes();
bytes[0] = (byte) Math.min(FILE_END_SIZE,bytes1.length-1);
for(int i=1;i<FILE_END_SIZE&&i<bytes1.length+1;i++){
bytes[i] = bytes1[i-1];
}
return bytes;
}
/**
* 获取文件名称
* @return
*/
private String getLastFileName(){
int i = fileName.lastIndexOf("\\");
int j = fileName.lastIndexOf("/");
if(i>=0&&i<fileName.length())return fileName.substring(i+1,fileName.length());
else if(j>=0&&j<fileName.length())return fileName.substring(j+1,fileName.length());
log.severe("获取文件名失败");
return null;
}
public void send(String fileName){
this.fileName = fileName;
this.start();
}
}
接收方
import java.io.*;
import java.net.*;
import java.util.Arrays;
import java.util.Random;
import java.util.logging.Logger;
public class ReceiveFile{
private static final Logger log = Logger.getLogger("ReceiveFile");
/**
* 接收的端口号
*/
private String port = "10086";
/**
* 接收的文件地址
*/
private String fileName = null;
/**
* 接收文件的缓冲区大小
*/
private static final int SEND_SIZE = 1024;
/**
* 文件接收结束符
*/
private byte[] FILE_END = null;
/**
* 入口函数
* @param args args[0]: 文件路径。 args[1]:端口号(默认:10086)
*/
public static void main(String[] args) {
if(args.length <= 0) {
System.out.println("需要参数 文件保存路径。");
System.exit(0);
}
ReceiveFile receiveFile = new ReceiveFile(args[0]);
if(args.length >= 2)receiveFile.port = args[2];
receiveFile.log.info("使用端口号:"+receiveFile.port);
receiveFile.start();
}
public ReceiveFile(String fileName) {
this.fileName = fileName;
}
public ReceiveFile() {}
public ReceiveFile(String port, String fileName) {
this.port = port;
this.fileName = fileName;
}
public void start(){
if(fileName==null||fileName.equals("")){
log.severe("文件名不能为空");
}
File file = new File(fileName);
if(file.mkdirs())log.warning("系统路径不存在,创建系统指定路径。");
FileOutputStream fileOutputStream = null;
//创建数据缓冲区
byte [] receiveBytes = new byte[SEND_SIZE];
//建立UDP连接
DatagramSocket datagramSocket = null;
DatagramPacket p = null;
try {
long st = System.currentTimeMillis();
datagramSocket = new DatagramSocket(Integer.parseInt(port));
p = new DatagramPacket(receiveBytes,SEND_SIZE);
while(true){
if(FILE_END==null)log.info("接收文件结束符");
//获取实际接收的数据缓冲区长度
datagramSocket.receive(p);
int length = p.getLength();
if(FILE_END==null){ //第一次发送的为文件结束标志
log.info("接收文件结束符成功,长度:"+length);
FILE_END = Arrays.copyOf(receiveBytes, length);
//接受文件名
if(fileName.charAt(fileName.length()-1)!='\\'&&fileName.charAt(fileName.length()-1)!='/')fileName+="\\";
fileName = fileName + getfileName(receiveBytes,length);
//创建文件
file = new File(fileName);
if(!file.exists())file.createNewFile();
fileOutputStream = new FileOutputStream(file);
log.info("创建文件"+fileName+"成功");
}else{
if(isFileEnd(receiveBytes,length)){ //是否传输完毕
break;
}
//文件写入
fileOutputStream.write(receiveBytes,0,length);
log.info("接受数据包,长度:"+length);
}
//重新设置缓冲区长度
p.setLength(SEND_SIZE);
}
log.info("文件接收完毕,用时:"+((System.currentTimeMillis()-st)/1000)+" s");
}catch (SocketException e){
log.severe("UDP 链接初始化失败,错误信息:"+e.getMessage());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
log.severe("文件创建失败,请手动创建。错误信息;"+e.getMessage());
} finally {
if(fileOutputStream!=null) {
try {
fileOutputStream.close();
if(datagramSocket!=null)datagramSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 根据文件结束符获取文件名称
* @param receiveBytes
* @param length
* @return
*/
private String getfileName(byte[] receiveBytes, int length) {
int len = receiveBytes[0];
return new String(receiveBytes, 1, Math.min(len+1,length-1));
}
/**
* 判断文件是否传输完毕
* @param bytes
* @return
*/
private boolean isFileEnd(byte[] bytes,int length){
if(bytes==null || length!= FILE_END.length)return false;
for(int i=0 ; i<FILE_END.length ; i++){
if(FILE_END[i]!=bytes[i])return false;
}
return true;
}
public void receive(String fileName){
this.fileName = fileName;
start();
}
}