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

因为本人是在本机测试的🙁,所以估计应该是有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; //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();
        }


    }

}
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值