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;}}}}
