因为本人是在本机测试的🙁,所以估计应该是有BUG的,请各位大佬指出
题目
使用UDP套接字实现文件传输 实现任意类型的文件传输 不限定文件大小,测试时至少要用10M以上大小的文件测试
分析
因为UDP是不可靠传输,中途可能存在丢包问题,所以解决思路是,客服端发一次访问请求等到服务端响应,只有第一次响应后,才能证明客户端的数据库包是可能达到服务器。客户端每发一次包,都等待服务器响应确认是否已经达到后,客户端才能再次发送数据包。
测试截图
客户端
服务端 测试结果截图
udpFileClient客户端请求上传文件
import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
public class udpFileClient {
private String fileName="D:/desktop/video.mp4";
private int serverPort=16667;
private InetAddress serverIp=null;
private DatagramSocket socket=null;
private DatagramPacket datagramPacket=null;
private byte[] successMark= "success data mark".getBytes();
private byte[] overMark= "over mark".getBytes();
public udpFileClient(){
try {
serverPort=16667;
serverIp=InetAddress.getByName("localhost");
socket=new DatagramSocket(16666);
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean presendFile(){
try {
String msg="client file:"+this.fileName;
datagramPacket=new DatagramPacket(msg.getBytes(),msg.length(),serverIp,serverPort);
socket.send(datagramPacket);
datagramPacket=new DatagramPacket(new byte[1024],1024);
socket.receive(datagramPacket);
msg=new String(datagramPacket.getData(),
0,datagramPacket.getLength());
System.out.println("msg:"+msg);
if(msg.equals("server: can transport file")){
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public boolean check(byte[]send,byte[]receive){
if(receive==null||receive.length==0){
return false;
}
for(int i=0;i<Math.min(send.length,receive.length);i++){
if(send[i]!=receive[i]){
return false;
}
}
return true;
}
public void sendFile(String FileName){
fileName=FileName;
try {
RandomAccessFile accessFile = new RandomAccessFile(fileName, "r");
int readSize=-1;
int sendCount=0,sendGroup=0;
byte []buf=new byte[1024];
byte []receiveBuf=new byte[1024];
String msg=null;
datagramPacket=new DatagramPacket(buf,1024,serverIp,serverPort);
while((readSize = accessFile.read(buf,0,buf.length)) != -1){
datagramPacket.setData(buf,0,readSize);
socket.send(datagramPacket);
sendCount++;
while(true){
datagramPacket.setData(receiveBuf,0,receiveBuf.length);
socket.receive(datagramPacket);
System.out.println("receiveBuf:"+receiveBuf+" VS successMark:"+successMark);
System.out.println("receiveBuf String:"+new String(receiveBuf,0,receiveBuf.length,StandardCharsets.UTF_8)+" VS successMark String:"+new String(successMark));
if(check(successMark,receiveBuf)){
sendGroup++;
break;
}else{
System.out.println("resend sendGroup:"+sendGroup+1);
System.out.println("resend sendCount:"+sendCount++);
datagramPacket.setData(buf,0,readSize);
socket.send(datagramPacket);
}
}
}
System.out.println("over mark");
datagramPacket.setData(overMark,0,overMark.length);
socket.send(datagramPacket);
}
catch (Exception e) {
e.printStackTrace();
}
finally {
socket.close();
}
}
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
udpFileClient udpFileClient = new udpFileClient();
System.out.println("尝试连接服务端......");
if(udpFileClient.presendFile()){
System.out.println("连接服务器成功,开始发送文件......");
udpFileClient.sendFile(udpFileClient.fileName);
}else {
System.out.println("网络不稳定,连接服务器失败....");
}
}
}
udpFileServer 服务端响应接受文件
import java.io.*;
import java.net.*;
public class udpFileServer {
private String filename="";
private int clientPort=16666;
private InetSocketAddress clientIp=null;
private DatagramSocket socket=null;
private DatagramPacket datagramPacket=null;
private byte[] successMark= "success data mark".getBytes();
private byte[] overMark= "over mark".getBytes();
public udpFileServer(){
try {
clientPort=16666;
clientIp=new InetSocketAddress(InetAddress.getByName("localhost"),clientPort);
socket=new DatagramSocket(16667, InetAddress.getByName("localhost"));
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.println("UDP FILE SERVER START...");
udpFileServer udpFileServer = new udpFileServer();
udpFileServer.run();
}
public boolean check(byte[]send,byte[]receive){
if(receive==null||receive.length==0){
return false;
}
for(int i=0;i<Math.min(send.length,receive.length);i++){
if(send[i]!=receive[i]){
return false;
}
}
return true;
}
public void run() {
try {
byte[] buf = new byte[1024];
datagramPacket=new DatagramPacket(buf,0,1024,clientIp);
socket.receive(datagramPacket);
String msg = new String(buf,0,datagramPacket.getLength());
System.out.println("客服端ip:"+datagramPacket.getAddress()+" port:"+datagramPacket.getPort()+" -》 "+msg);
msg = msg.substring(12);
for(int i=msg.length()-1;i>=0;i--){
if(msg.charAt(i)=='.'){
filename=msg.substring(0,i)+"(1)"+msg.substring(i);
break;
}
}
System.out.println("新文件名:"+filename);
datagramPacket.setData(("server: can transport file").getBytes());
socket.send(datagramPacket);
File file = new File(filename);
if(file.exists()){
file.delete();
System.out.println("文件已存在,删除后新创建");
}
int reciveCount=0;
int readSize=0;
datagramPacket=new DatagramPacket(buf,0,1024);
socket.receive(datagramPacket);
System.out.println("reciveCount:"+reciveCount++);
FileOutputStream fileOutputStream = new FileOutputStream(filename);
while((readSize=datagramPacket.getLength())!=0){
msg = new String(buf,0, readSize);
System.out.println(msg);
if(check(overMark,buf)){
System.out.println("over mark");
break;
}
fileOutputStream.write(buf,0,readSize);
fileOutputStream.flush();
datagramPacket.setData(successMark,0,successMark.length);
System.out.println("successMark"+successMark);
socket.send(datagramPacket);
datagramPacket.setData(buf,0,buf.length);
socket.receive(datagramPacket);
System.out.println("reciveCount:"+reciveCount++);
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
socket.close();
}
}
}
|