java使用UDP发送文件

环境

maven 3.6

jdk 1.8

udp-nio 分支支持批量发送

服务端源码(接收文件)

package com.banywl.file.transfer.udp;

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.SocketException;

/**

* 文件接收服务器

*/

public class UDPFileServer {

/**

* socket 缓冲区

*/

private DatagramSocket socket;

/**

* 文件包数据大小

*/

private int packetSize;

/**

* 名称长度值占用4字节

* 文件长度值占用8字节

*/

private byte[] fileInfo = new byte[12];

/**

* packet 缓冲区

*/

private byte[] packetBuf;

/**

* 文件名长度值用4字节缓冲区接收 int 值

*/

private DatagramPacket fileNameLenPacket;

/**

* 文件长度值使用8字节缓冲区接收 long 值

*/

private DatagramPacket fileLenPacket;

/**

* 文件数据封包使用512字节缓冲区分段接收

*/

private DatagramPacket filePacket;

/**

* 接收到的文件名

*/

private String fileName;

/**

* 接收到的文件内容

*/

private byte[] fileData;

/**

* 初始化文件接收UDP服务

*

* @param port 监听端口

* @param packetSize 封包大小

* @throws SocketException

*/

public UDPFileServer(int port, int packetSize) throws SocketException {

this.socket = new DatagramSocket(port);

this.packetSize = packetSize;

this.packetBuf = new byte[packetSize];

fileNameLenPacket = new DatagramPacket(fileInfo, 4);

fileLenPacket = new DatagramPacket(fileInfo, 4,8);

filePacket = new DatagramPacket(packetBuf, this.packetSize);

}

/**

* 接收文件,

* udp 包顺序: 1、文件名长度值 2、文件长度值 3、文件名 4、文件内容

*

* @return 文件内容字节数组

* @throws IOException

*/

public void receiveFile() throws IOException {

// 读取文件名长度

this.socket.receive(fileNameLenPacket);

// 读取文件长度

this.socket.receive(fileLenPacket);

// 取回文件名

byte[] fileNameBuf = new byte[Utils.bytesToInt(this.fileInfo)];

DatagramPacket fnPacket = new DatagramPacket(fileNameBuf, fileNameBuf.length);

this.socket.receive(fnPacket);

this.fileName = new String(fileNameBuf);

// 建立文件缓冲区,读取文件内容到缓冲区

int fileLen = (int) Utils.bytesToLong(this.fileInfo,4);

this.fileData = new byte[fileLen];

int writePos = 0;

while (writePos != fileLen) {

// 取回文件内容

this.socket.receive(filePacket);

if (writePos + this.packetSize < fileLen) {

System.arraycopy(packetBuf, 0, this.fileData, writePos, this.packetSize);

writePos += this.packetSize;

} else {

int rsize = fileLen - writePos;

System.arraycopy(packetBuf, 0, this.fileData, writePos, rsize);

writePos += rsize;

}

System.out.println(String.format("已接收:%.4f",(double)writePos / (double) fileLen));

}

System.out.println("接收完成");

}

public void close() {

this.socket.close();

}

public String getFileName() {

return fileName;

}

public byte[] getFileData() {

return fileData;

}

}

UDP客户端源码(发送文件)

package com.banywl.file.transfer.udp;

import java.io.*;

import java.net.*;

import java.util.concurrent.TimeUnit;

/**

* 文件发送客户端

*/

public class UDPFileClient {

private InetAddress address;

private int port;

/**

* 包大小

*/

private int packetSize;

/**

* 文件包

*/

private byte[] packetBuf;

/**

* 名称长度值占用4字节

* 文件长度值占用8字节

*/

private byte[] fileInfoBuf = new byte[12];

/**

* 文件名 packet

*/

private DatagramPacket fileNameLenPacket;

/**

* 文件长度 packet

*/

private DatagramPacket fileLenPacket;

/**

* 文件数据 packet

*/

private DatagramPacket filePacket;

private DatagramSocket socket = new DatagramSocket();

/**

* 初始化文件发送

* @param hostname 目标主机名称

* @param port 目标端口

* @param packetSize 封包大小

* @throws UnknownHostException

* @throws SocketException

*/

public UDPFileClient(String hostname, int port,int packetSize) throws UnknownHostException, SocketException {

this.address = InetAddress.getByName(hostname);

this.port = port;

this.packetSize = packetSize;

this.packetBuf = new byte[this.packetSize];

// 文件名长度值用4字节

this.fileNameLenPacket = new DatagramPacket(this.fileInfoBuf,4,this.address,port);

// 文件长度使用8字节

this.fileLenPacket = new DatagramPacket(this.fileInfoBuf,4,8,this.address,port);

// 文件使用512字节分段发送

this.filePacket = new DatagramPacket(packetBuf,this.packetSize,this.address,port);

}

/**

* udp 包顺序: 1、文件名长度值 2、文件长度值 3、文件名 4、文件内容

* @param filePath 文件路径

* @throws IOException

*/

public void sendFile(String filePath) throws IOException {

// 读取系统文件

File file = new File(filePath);

byte[] fileBuf = new byte[(int)file.length()];

byte[] readBuf = new byte[2048];

int readLen,staPos = 0;

FileInputStream inputStream =new FileInputStream(file);

while ((readLen = inputStream.read(readBuf))!=-1){

System.arraycopy(readBuf,0,fileBuf,staPos,readLen);

staPos += readLen;

}

// 发送文件名长度值和文件长度值

System.arraycopy(Utils.intToBytes(file.getName().getBytes().length),0,this.fileInfoBuf,0,4);

System.arraycopy(Utils.longToBytes(file.length()),0,this.fileInfoBuf,4,8);

socket.send(fileNameLenPacket);

socket.send(fileLenPacket);

// 发送文件名

DatagramPacket fileNamPacket = new DatagramPacket(file.getName().getBytes(),file.getName().getBytes().length,address,port);

socket.send(fileNamPacket);

// 发送文件

int readIndex = 0;

while (readIndex != fileBuf.length){

if(readIndex + this.packetSize < fileBuf.length){

System.arraycopy(fileBuf,readIndex,packetBuf,0,this.packetSize);

readIndex += this.packetSize;

}else{

int rsize = fileBuf.length - readIndex;

System.arraycopy(fileBuf,readIndex,packetBuf,0,rsize);

readIndex += rsize;

}

socket.send(filePacket);

System.out.println(String.format("已发送:%.4f",(double)readIndex / (double) file.length()));

try {

TimeUnit.MILLISECONDS.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println("发送完成");

}

public void close(){

this.socket.close();

}

}

例子(Application.java)

package com.banywl.file.transfer.udp;

import java.io.*;

import java.net.SocketException;

import java.net.UnknownHostException;

import java.util.Scanner;

public class Application {

/**

* -server 18888 10240

* -client 255.255.255.255 18888 10240 path/to/file

* @param args

*/

public static void main(String[] args) {

String baseDir = System.getProperty("user.dir") ;

System.out.println(baseDir);

if (args.length == 0) {

System.out.println("参数错误!");

System.exit(0);

}

if ("-server".equals(args[0])) {

System.out.println("启动服务端");

int port = Integer.parseInt(args[1]);

int size = args.length == 2 ? 1024 : Integer.parseInt(args[2]);

try {

UDPFileServer server = new UDPFileServer(port,size);

while (true){

System.out.println("等待接收");

server.receiveFile();

System.out.println("收到文件:"+ server.getFileName());

File file = new File(baseDir + File.separator+ "receive" + File.separator+server.getFileName());

if (!file.getParentFile().exists()){

file.getParentFile().mkdir();

}

FileOutputStream fo = new FileOutputStream(file);

fo.write(server.getFileData());

fo.close();

System.out.println("是否退出(Y/N)?");

Scanner scanner = new Scanner(System.in);

if ("y".equalsIgnoreCase(scanner.next())){

break;

}

}

server.close();

System.out.println("服务器已关闭");

} catch (SocketException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}else if("-client".equals(args[0])){

System.out.println("启动客户端");

String ip = args[1];

int port = Integer.parseInt(args[2]);

int size = Integer.parseInt(args[3]);

String pathname = args[4];

try {

UDPFileClient client = new UDPFileClient(ip,port,size);

client.sendFile(pathname);

client.close();

System.out.println("发送完成");

} catch (UnknownHostException e) {

e.printStackTrace();

} catch (SocketException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

java udp传输文件_JAVA使用UDP收发文件相关推荐

  1. java上传加密_Java上传下载文件并实现加密解密

    使用 Jersey 服务器实现上传,使用 HTTP 请求实现下载 引入依赖 在 pom.xml 中添加 Jersey 相关依赖 com.sun.jersey jersey-client 1.18.1 ...

  2. java文件打包jar文件_Java打包成jar文件,以及将jar文件导出为exe文件方法汇总(图形说明)...

    方法一:用j2ewiz,使用方法如下: 操作步骤: 1.         双击j2ewiz.exe,出现软件注册窗口,点击下一步. 2.         选择待转换的Jar文件及最低Jvm版本.我选择 ...

  3. java fileupload 文件_java用Commons fileupload 文件的上传

    java用Commons fileupload 文件的上传 基于表单的文件上传 如果在表单中使用表单元素 />,浏览器在解析表单时,会自动生成一个输入框和一个按钮,输入框可供用户填写本地文件的文 ...

  4. doc无法编译java文件_java编译成jar文件.doc

    java编译成jar文件 Java程序打包成jar包 (2012-06-08 10:28:23) 转载▼ 标签: 分类: 方法一:通过jar命令 jar命令的用法: 下面是jar命令的帮助说明: 用法 ...

  5. java代码实现解压文件_Java压缩/解压文件的实现代码

    用java压缩/解压文件: import java.io.*; import java.awt.*; import java.awt.event.*; import java.util.*; impo ...

  6. java从url下载文件_Java从URL下载文件

    在这篇文章中将学习如何从java下载URL中的文件.使用java.net.URL openStream()方法从java程序中的URL下载文件.也可以使用Java NIO Channels或Java ...

  7. java 保存本地文件_java如何实现保存文件到本地

    java如何实现保存文件到本地 发布时间:2020-04-30 11:20:24 来源:亿速云 阅读:773 作者:小新 java如何实现保存文件到本地?相信有很多人都不太了解,今天小编为了让大家更加 ...

  8. java 按字节读入_Java按字节读取文件

    [题外话]今天学习了Object-c.通过看书发现,Object-c跟大多数面向对象的语言一样,是很有意思的语言.里面的语法跟Java还有C++,形式上有些差异.至于我为什么要学OC,这个是因为工作需 ...

  9. java object取数据_java使用ObjectInputStream从文件中读取对象

    import java.io.EOFException; import java.io.FileInputStream; import java.io.FileNotFoundException; i ...

最新文章

  1. 使用EntityFramework6连接MySql数据库(db first方式)
  2. ETSI MEC — 参考架构模型
  3. rand和srand
  4. sql可视化工具_数据分析该用什么工具?
  5. java byte 转换int_java byte负数转换int失真?
  6. java web 局部刷新页面_如何实现页面局部刷新(Java)
  7. 强大的离线字典《Colordict》+多种词库下载地址
  8. 基于单片机的指纹密码锁系统
  9. JSON RPC API
  10. 分享收集软件教程的微信小程序
  11. Linux下如何使用qt和anjuta来单步调试caffe的代码
  12. 等额本金等额本息推导
  13. koolshare DDNS 配置
  14. UnicodeDecodeError: ‘gb2312‘ codec can‘t decode byte 0xe9 in position 5632: illegal multibyte sequen
  15. Raptor 经典例题 2 (冒泡法排序 100名同学拉成一圈)
  16. 动态规划——钢条切割
  17. 代码库_单精度浮点减法器
  18. Maven插件列表_Maven插件查询_Maven插件查看
  19. FPGA数字信号处理(四)Quartus FIR IP核实现
  20. EOS智能合约开发系列(11): 多重签名

热门文章

  1. 混合文件下分离xml文件和jpg文件
  2. 概率图模型中的变量消除顺序
  3. 关于VECTOR和DEQUE
  4. Veeam在思科2017年合作伙伴峰会上荣获ISV年度最佳合作伙伴全球奖
  5. Hive权限与HDFS权限分离导致的一些问题
  6. Swift语言快速入门
  7. nginx添加ssl证书认证
  8. 不能在此路径中使用此配置节。如果在父级别上锁定了该节,便会出现这种情况...
  9. php中的var_dump()方法的详细说明
  10. 从客户端(Content=EM STRONG U 这是测试这...)中检测到有潜在危险的Request.Form 值。...