UDP简单大文件传送 发表于 2017-12-04 | | 阅读次数: 话不多说,直接上代码。运行的时候先运行You.java, 再运行My.javaMy.java123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132import java.net.*;import java.util.concurrent.TimeoutException;import java.awt.event.*;import java.io.File;import java.io.IOException;import java.io.RandomAccessFile;import javax.swing.*;public class My{ public static void main(String[] args) { new MyFrame(); }}class MyFrame extends JFrame implements ActionListener { JTextField out_message = new JTextField(16); JTextArea in_message = new JTextArea(); JButton cfile = new JButton("选择文件"); JFileChooser chooser = new JFileChooser(); public MyFrame() { setTitle("My"); // setSize(600, 600); setVisible(true); setBounds(300, 200, 350, 300); cfile.addActionListener(this); // send.addActionListener(this); // out_message.addKeyListener(this); JPanel pSouth = new JPanel(); pSouth.add(out_message); pSouth.add(cfile); // pSouth.add(send); add(pSouth, "South"); add(new JScrollPane(in_message), "Center"); validate(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void actionPerformed(ActionEvent event) { chooser.setFileSelectionMode(0); int status = chooser.showOpenDialog(null); if (status == 1) { return; } else { File file = chooser.getSelectedFile(); out_message.setText(file.getAbsolutePath()); out_message.grabFocus(); long startTime = System.currentTimeMillis();// 获取当前时间 byte[] buf = new byte[UDPUtils.BUFFER_SIZE];// 发送文件的字节数组 byte[] receiveBuf = new byte[Math.max(UDPUtils.successData.length, UDPUtils.exitData.length)];// 传送验证信息的字节数组 RandomAccessFile accessFile = null; DatagramPacket dpk = null; DatagramSocket dsk = null; int readSize = -1; try { accessFile = new RandomAccessFile(file.getAbsolutePath(), "r");// 创建一个只读的文件流 dpk = new DatagramPacket(buf, buf.length, new InetSocketAddress(InetAddress.getByName("192.168.199.143"), UDPUtils.PORT + 1));// 创建一个待发送数据包 dsk = new DatagramSocket(UDPUtils.PORT);// 接收.... dsk.setSoTimeout(1000);// 设置确认报文超时重传 int sendCount = 0;// 记录发送的数据包的数量 while ((readSize = accessFile.read(buf, 0, buf.length)) != -1) {// 将文件的数据读满字节数组,返回读入数组的总字节数,如果到文件尾则等于-1 // 未读到文件尾 dpk.setData(buf, 0, readSize);// 设置包的缓冲区长度为读入的字节数 dsk.send(dpk);// 发送包 // 等待服务端回应 { while (true) { dpk.setData(receiveBuf, 0, receiveBuf.length);// UDPUtils.successData.length); try { dsk.receive(dpk);// 接收数据包 if (!UDPUtils.isEqualsByteArray(UDPUtils.successData, receiveBuf, dpk.getLength())) {// 返回的不是成功标志 throw new TimeoutException("数据没有收到!"); } else { break; } } catch (SocketTimeoutException | TimeoutException e) {//没有收到数据包或返回的不是成功标志 // TODO 超时重传 System.out.println("resend ..."); dpk.setData(buf, 0, readSize); dsk.send(dpk); continue; } } } System.out.println("send count of " + (++sendCount) + "!"); } // 发送退出标志等待回应 System.out.println("客户端退出 ...."); dpk.setData(UDPUtils.exitData, 0, UDPUtils.exitData.length); dsk.send(dpk); while (true) { dpk.setData(receiveBuf, 0, receiveBuf.length); // byte[] receiveData = dpk.getData(); try { dsk.receive(dpk); if (!UDPUtils.isEqualsByteArray(UDPUtils.exitData, receiveBuf, dpk.getLength())) { throw new TimeoutException("Msg not equal"); } else { break; } } catch (SocketTimeoutException | TimeoutException e) { // TODO 超时重传 System.out.println("client Resend exit message ...."); dsk.send(dpk); continue; } } } 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)); } }} You.java123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869import java.io.BufferedOutputStream;import java.io.FileOutputStream;import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;import java.net.InetSocketAddress;public class You { private static final String SAVE_FILE_PATH = "C:/Users/马冲/Desktop/flag.zip";//接收文件存储的路径 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("127.0.0.1"), UDPUtils.PORT)); dsk = new DatagramSocket(UDPUtils.PORT + 1);//创建一个数据包由于接收 bos = new BufferedOutputStream(new FileOutputStream(SAVE_FILE_PATH));//创建一个缓冲的文件输出流 System.out.println("等待客户端...."); dsk.receive(dpk);//等待客户端发送文件 int readSize = 0; int readCount = 0; int flushSize = 0; while ((readSize = dpk.getLength()) != 0) { // 验证客户端发送退出标志 if (UDPUtils.isEqualsByteArray(UDPUtils.exitData, buf, readSize)) { System.out.println("服务器退出 ..."); 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(); } } }} UDPUtils.java1234567891011121314151617181920212223242526272829303132333435363738394041424344public 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(); /** * 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 || 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; }} Your support will encourage me to continue to create! Donate WeChat Pay Alipay