java file transfer udp client_UDP:Java实现简单大文件传输 分...

今天闲来无事,想起过几天要写一个UDP文件传输的插件服务,于是下午就动手写了个UDP文件传输的小代码. 个人觉得还挺有意思的,对UDP感兴趣的小伙伴可以参考看看哦.

好了,下面直接上代码.

1.UDPServer.java

复责接收文件,保存.

package com.bill.udp.server;

import java.io.BufferedOutputStream;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

import java.net.InetSocketAddress;

import com.bill.udp.util.UDPUtils;

/**

* Test file transfer of Server

* @author Bill QQ:593890231

* @since v1.0 2014/09/21

*

*/

public class UDPServer {

private static final String SAVE_FILE_PATH = "E:/2013.mkv";

public static void main(String[] args) {

byte[] buf = new byte[UDPUtils.BUFFER_SIZE];

DatagramPacket dpk = null;

DatagramSocket dsk = null;

BufferedOutputStream bos = null;

try {

dpk = new DatagramPacket(buf, buf.length,new InetSocketAddress(InetAddress.getByName("localhost"), UDPUtils.PORT));

dsk = new DatagramSocket(UDPUtils.PORT + 1, InetAddress.getByName("localhost"));

bos = new BufferedOutputStream(new FileOutputStream(SAVE_FILE_PATH));

System.out.println("wait client ....");

dsk.receive(dpk);

int readSize = 0;

int readCount = 0;

int flushSize = 0;

while((readSize = dpk.getLength()) != 0){

// validate client send exit flag

if(UDPUtils.isEqualsByteArray(UDPUtils.exitData, buf, readSize)){

System.out.println("server exit ...");

// send exit flag

dpk.setData(UDPUtils.exitData, 0, UDPUtils.exitData.length);

dsk.send(dpk);

break;

}

bos.write(buf, 0, readSize);

if(++flushSize % 1000 == 0){

flushSize = 0;

bos.flush();

}

dpk.setData(UDPUtils.successData, 0, UDPUtils.successData.length);

dsk.send(dpk);

dpk.setData(buf,0, buf.length);

System.out.println("receive count of "+ ( ++readCount ) +" !");

dsk.receive(dpk);

}

// last flush

bos.flush();

} catch (Exception e) {

e.printStackTrace();

} finally{

try {

if(bos != null)

bos.close();

if(dsk != null)

dsk.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

2.UDPClient.java

读取文件,并发送数据包传输文件

package com.bill.udp.client;

import java.io.IOException;

import java.io.RandomAccessFile;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

import java.net.InetSocketAddress;

import com.bill.udp.util.UDPUtils;

/**

* Test File transfer of Client

* @author Bill QQ:593890231

* @since v1.0 2014/09/21

*/

public class UDPClient {

private static final String SEND_FILE_PATH = "D:/2013.mkv";

public static void main(String[] args){

long startTime = System.currentTimeMillis();

byte[] buf = new byte[UDPUtils.BUFFER_SIZE];

byte[] receiveBuf = new byte[1];

RandomAccessFile accessFile = null;

DatagramPacket dpk = null;

DatagramSocket dsk = null;

int readSize = -1;

try {

accessFile = new RandomAccessFile(SEND_FILE_PATH,"r");

dpk = new DatagramPacket(buf, buf.length,new InetSocketAddress(InetAddress.getByName("localhost"), UDPUtils.PORT + 1));

dsk = new DatagramSocket(UDPUtils.PORT, InetAddress.getByName("localhost"));

int sendCount = 0;

while((readSize = accessFile.read(buf,0,buf.length)) != -1){

dpk.setData(buf, 0, readSize);

dsk.send(dpk);

// wait server response

{

while(true){

dpk.setData(receiveBuf, 0, receiveBuf.length);

dsk.receive(dpk);

// confirm server receive

if(!UDPUtils.isEqualsByteArray(UDPUtils.successData,receiveBuf,dpk.getLength())){

System.out.println("resend ...");

dpk.setData(buf, 0, readSize);

dsk.send(dpk);

}else

break;

}

}

System.out.println("send count of "+(++sendCount)+"!");

}

// send exit wait server response

while(true){

System.out.println("client send exit message ....");

dpk.setData(UDPUtils.exitData,0,UDPUtils.exitData.length);

dsk.send(dpk);

dpk.setData(receiveBuf,0,receiveBuf.length);

dsk.receive(dpk);

// byte[] receiveData = dpk.getData();

if(!UDPUtils.isEqualsByteArray(UDPUtils.exitData, receiveBuf, dpk.getLength())){

System.out.println("client Resend exit message ....");

dsk.send(dpk);

}else

break;

}

}catch (Exception e) {

e.printStackTrace();

} finally{

try {

if(accessFile != null)

accessFile.close();

if(dsk != null)

dsk.close();

} catch (IOException e) {

e.printStackTrace();

}

}

long endTime = System.currentTimeMillis();

System.out.println("time:"+(endTime - startTime));

}

}

3.UDPUtils.java

简单UDP工具类

package com.bill.udp.util;

/**

* UDP transfer Utils

* @author Bill QQ:593890231

* @since v1.0 2014/09/21

*/

public class UDPUtils {

private UDPUtils(){}

/** transfer file byte buffer **/

public static final int BUFFER_SIZE = 50 * 1024;

/** controller port **/

public static final int PORT = 50000;

/** mark transfer success **/

public static final byte[] successData = "success data mark".getBytes();

/** mark transfer exit **/

public static final byte[] exitData = "exit data mark".getBytes();

public static void main(String[] args) {

byte[] b = new byte[]{1};

System.out.println(isEqualsByteArray(successData,b));

}

/**

* compare byteArray equest successData

* @param compareBuf

* @param buf

* @return

*/

public static boolean isEqualsByteArray(byte[] compareBuf,byte[] buf){

if (buf == null || buf.length == 0)

return false;

boolean flag = true;

if(buf.length == compareBuf.length){

for (int i = 0; i < buf.length; i++) {

if(buf[i] != compareBuf[i]){

flag = false;

break;

}

}

}else

return false;

return flag;

}

/**

* compare byteArray equest successData

* @param compareBuf src

* @param buf target

* @return

*/

public static boolean isEqualsByteArray(byte[] compareBuf,byte[] buf,int len){

if (buf == null || buf.length == 0 || buf.length < len || compareBuf.length < len)

return false;

boolean flag = true;

int innerMinLen = Math.min(compareBuf.length, len);

//if(buf.length == compareBuf.length){

for (int i = 0; i < innerMinLen; i++) {

if(buf[i] != compareBuf[i]){

flag = false;

break;

}

}

//}else

//return false;

return flag;

}

}

按照自己的思路,UDP丢包比较严重,开始自己实现的时候没有注意request/response的问题.也就是每次传完一个数据包双方进行握手,表示传输成功.丢包太严重.

于是后面设计了个简单的校验,client发送之后,等待server响应成功,client继续传递下一部分数据包.直至最后整个文件传输完成.进行最后一次握手,通讯结束.

由于是自己写的一个小测试,代码比较简单,没有考虑到相关线程,性能问题. 不过项目中估计要复杂些了.  希望各位小伙伴能给点意见,一起交流学习..

smile.gif

单机测试,传输1.3G的的mkv视频,与原文件大小一致,视频能正常播放,没有损坏.

这里是喜欢技术,喜欢学习,喜欢交友的 Bill  ....

版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值