UDP协议不面向连接,提供不可靠传输,使用UDP协议传输文件时发送方和接收方不需要建立连接,发送方直接将数据报包扔进网络,包就会自行寻找目标IP及端口,如果目标端口没开不会报错但会发生丢包
import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
/**
* 利用网络传输数据
*/
public class Client {
public static void clientSend(byte[] data, int len, InetSocketAddress server) throws IOException {
//1、使用DatagramSocket创建发送端
DatagramSocket client = new DatagramSocket(6666);
//2、准备数据,数据必须是字符数组
//3、数据打包
DatagramPacket packet = new DatagramPacket(data,0, len, server);
//4、发送数据
client.send(packet);
//5、释放资源
client.close();
}
}
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
/**
* 将文件分块后每块单独发送
*/
public class Subsection{
private final File src;
private final int blockSize;
private int blockNum;
private long len;
InetSocketAddress server = new InetSocketAddress("localhost", 8888);//"192.168.1.26";
public Subsection(String filePath, int blockSize) {
this.src = new File(filePath);
//每块多大
this.blockSize = blockSize;
init();
}
//初始化
private void init(){
//一共读多少字节:这里读整个文件
len = src.length();
//一共分多少块:文件大小除每块大小并向上取整
blockNum = (int)Math.ceil(len*1.0/blockSize);
}
//将文件分割成块
public void split() throws IOException, InterruptedException {
//定义开始位置
int beginPos;
//定义实际上要读多长,因为不一定每一次都会读满一块的内容
int actualSize;
for(int i = 0; i<blockNum; i++){
//设置开始位置,当i=0即第一块时,从0即第一个字节开始,当i=1即第二块时,从第1024个字节即第一块的最后一个字节的下一个字节开始
beginPos = i * blockSize;
if( i == blockNum-1 ){
//若是最后一块,就读取剩余长度个大小
actualSize = (int)len;
}else{
//若不是最后一块,就将一块读满,然后用文件的大小减去一块的长度,算出剩余长度
actualSize = blockSize;
len -= blockSize;
}
toBlock(i, beginPos, actualSize);
}
String flag = "false";
Client.clientSend(flag.getBytes(StandardCharsets.UTF_8), flag.getBytes(StandardCharsets.UTF_8).length, server);
}
//将分割为块的数据装入容器并输出到文件
private void toBlock(int i, int beginPos, int actualSize) throws IOException, InterruptedException {
byte[] flush = new byte[blockSize];
int cut, j;
j = i+1;
//输入源
RandomAccessFile raf = new RandomAccessFile(src, "r");
System.out.println("第"+j+"个包:从第"+beginPos+"字节开始,发送"+actualSize+"个字节");
raf.seek(beginPos);
cut = raf.read(flush);
Client.clientSend(flush, Math.min(actualSize, cut), server);
raf.close();
Thread.sleep(10);
}
}
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* 分块接收数据
*/
public class Server {
public static void serverReceive(String filepath) throws IOException {
//1、使用DatagramSocket创建接收端
DatagramSocket server = new DatagramSocket(8888);
//2、准备容器,封装为DatagramPacket包
byte[] container = new byte[1024*10];
String str;
int i = 1;
DatagramPacket packet = new DatagramPacket(container, 0, container.length);
File destfile = new File(filepath);
while(true) {
//3、接收数据
server.receive(packet);
//4、分析数据
byte[] data = packet.getData();
int len = packet.getLength();
str = new String(data, 0, len);
if (!str.equals("false")) {
System.out.println("收到第"+i+"个包,大小"+len+"字节");
FileUtils.writeByteArrayToFile(destfile, data, true);
i++;
}
else {
System.out.println("STOP");
//5、释放资源
server.close();
return;
}
}
}
}