今天闲来无事,想起过几天要写一个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;
}
}
于是后面设计了个简单的校验,client发送之后,等待server响应成功,client继续传递下一部分数据包.直至最后整个文件传输完成.进行最后一次握手,通讯结束.
由于是自己写的一个小测试,代码比较简单,没有考虑到相关线程,性能问题. 不过项目中估计要复杂些了. 希望各位小伙伴能给点意见,一起交流学习..
单机测试,传输1.3G的的mkv视频,与原文件大小一致,视频能正常播放,没有损坏.
这里是喜欢技术,喜欢学习,喜欢交友的 Bill ....