刚学完Java,用UDP实现文件传输,实现有规律接收包。Java学得不是很好,希望高手看到指点一下。
还有部分代码未贴出,在下面附件中。
package com.way.server; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; import java.net.SocketException; public class Server extends Thread { private DatagramSocket receive; private String ip; private int serverPort; private int clientPort; private File file; private String path; private DatagramPacket pkg; private DatagramPacket messagepkg; public Server(String ip, int serverPort, int clientPort, String path) { super(); this.ip = ip; this.serverPort = serverPort; this.clientPort = clientPort; this.path = path; } public String getPath() { return path; } public String getip() { return ip; } public void setPath(String path) { this.ip = path; } public File getFile() { return file; } public void setFile(File file) { this.file = file; } public void receive() { try { // 接收文件监听端口 receive = new DatagramSocket(serverPort); // 写文件路径 BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(new File(path))); // 读取文件包 byte[] buf = new byte[1024 * 63]; pkg = new DatagramPacket(buf, buf.length); // 发送收到文件后 确认信息包 byte[] messagebuf = new byte[1024]; messagebuf = "ok".getBytes(); messagepkg = new DatagramPacket(messagebuf, messagebuf.length, new InetSocketAddress(ip, clientPort)); // 循环接收包,每接到一个包后回给对方一个确认信息,对方才发下一个包(避免丢包和乱序),直到收到一个结束包后跳出循环,结束文件传输,关闭流 while (true) { receive.receive(pkg); if (new String(pkg.getData(), 0, pkg.getLength()).equals("end")) { System.out.println("文件接收完毕"); bos.close(); receive.close(); break; } receive.send(messagepkg); System.out.println(new String(messagepkg.getData())); bos.write(pkg.getData(), 0, pkg.getLength()); bos.flush(); } bos.close(); receive.close(); } catch (SocketException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public void run() { receive(); } }
package com.way.client; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; import java.net.SocketException; public class Client extends Thread { private DatagramSocket send; private DatagramPacket pkg; private DatagramPacket messagepkg; private int serverPort; private int clientPort; private String path; private File file; private String ip; public Client(int serverPort, int clientPort, String path, String ip) { super(); this.serverPort = serverPort; this.clientPort = clientPort; this.path = path; this.ip = ip; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public String getIp() { return ip; } public void setIp(String ip) { this.ip = ip; } public void send() { try { //文件发送者设置监听端口 send = new DatagramSocket(clientPort); BufferedInputStream bis = new BufferedInputStream( new FileInputStream(new File(path))); //确认信息包 byte[] messagebuf = new byte[1024]; messagepkg = new DatagramPacket(messagebuf, messagebuf.length); //文件包 byte[] buf = new byte[1024 * 63]; int len; while ((len = bis.read(buf)) != -1) { pkg = new DatagramPacket(buf, len, new InetSocketAddress( ip, serverPort)); //设置确认信息接收时间,3秒后未收到对方确认信息,则重新发送一次 send.setSoTimeout(3000); while (true) { send.send(pkg); send.receive(messagepkg); System.out.println(new String(messagepkg.getData())); break; } } // 文件传完后,发送一个结束包 buf = "end".getBytes(); DatagramPacket endpkg = new DatagramPacket(buf, buf.length, new InetSocketAddress(ip, serverPort)); System.out.println("文件发送完毕"); send.send(endpkg); bis.close(); send.close(); } catch (SocketException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void run() { send(); } }