Java实现UDP套接字大文件可靠传输

因为本人是在本机测试的,所以估计应该是有BUG的,请各位大佬指出

题目

使用UDP套接字实现文件传输
实现任意类型的文件传输
不限定文件大小,测试时至少要用10M以上大小的文件测试

分析

因为UDP是不可靠传输,中途可能存在丢包问题,所以解决思路是,客服端发一次访问请求等到服务端响应,只有第一次响应后,才能证明客户端的数据库包是可能达到服务器客户端每发一次包,都等待服务器响应确认是否已经达到后,客户端才能再次发送数据包

测试截图

客户端

Java实现UDP套接字大文件可靠传输_第1张图片
服务端
Java实现UDP套接字大文件可靠传输_第2张图片
测试结果截图
Java实现UDP套接字大文件可靠传输_第3张图片

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; //localhost
    private DatagramSocket socket=null;  //16666
    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");
            //创建一个本地任意UDP套接字
            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 {
     
//            FileInputStream fileInputStream = new FileInputStream(fileName);
            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();
        }


    }

}

你可能感兴趣的:(JAVA,java)