花了将近两天的时间实现了使用Java Socket 模拟了一个简单的Ftp Server/Client,主要实现了文件上载、下传、删除以及目录浏览等操作,由于时间关系只能后面继续完善,先做一记录。
public FtpServer() { loadServerInfo(); int i = 0; try { ServerSocket s = new ServerSocket(Integer.parseInt(sInfo.getPort())); for(;;) { Socket incoming = s.accept(); FtpHandler h = new FtpHandler(incoming,i); h.start(); i++; } } catch(Exception e) { e.printStackTrace(); } }
public void run() // 监听客户端输入的指令 { try { out = new DataOutputStream(csocket.getOutputStream()); // 给客户端返回的流 DataInputStream in = new DataInputStream(csocket.getInputStream()); // 客户端发送来的信息 cmd = in.readUTF(); ServerUtil.outLogging(cmd); cmdArr = cmd.split(" "); if (cmdArr[0].equals("LINK")) loginServer(); if (cmdArr[0].equals("DOWN")) sendFile(); if(cmdArr[0].equals("UPDATE")) updateFile(); if(cmdArr[0].equals("GETDIR")) sendCurrentDirList(); if(cmdArr[0].equals("DELETE")) deleteFile(); if(cmdArr[0].equals("DELETE")) deleteFile(); csocket.close(); this.stop(); } catch (Exception e) { e.printStackTrace(); } }
public void run() { try { socket = new Socket(FtpClientJFrame.ip, FtpClientJFrame.port); in = new DataInputStream(socket.getInputStream()); // 服务器发送回来的消息 out = new DataOutputStream(socket.getOutputStream()); // 发送给服务端的消息 out.writeUTF(FtpClientJFrame.out); String rs = in.readUTF(); if (rs == "LOGINOK" || rs.equals("LOGINOK")) { JOptionPane.showMessageDialog(null, "连接成功!", "提示", JOptionPane.INFORMATION_MESSAGE); FtpClientMain.cInfo.setCurrentServerPath(in.readUTF()); FtpClientMain.cInfo.setLoginState(true); FtpClientMain.cInfo.setIpAdd(FtpClientJFrame.ip); FtpClientMain.cInfo.setPort(FtpClientJFrame.port); getDirList(); } else if (rs == "LOGINNO" || rs.equals("LOGINNO")) { JOptionPane.showMessageDialog(null, "用户名或者密码错误!", "提示", JOptionPane.INFORMATION_MESSAGE); } } catch (UnknownHostException e) { JOptionPane.showMessageDialog(null, "未找到对应主机!", "提示", JOptionPane.INFORMATION_MESSAGE); } catch (IOException e) { e.printStackTrace(); } }
public class ServerInfo { private String ipAdd; private String port; private String username; private String password; private String pathDir; private Boolean canUpdate; private Boolean canDelete; private Boolean canDownlaod; public Boolean getCanDelete() { return canDelete; } public void setCanDelete(Boolean canDelete) { this.canDelete = canDelete; } public Boolean getCanDownlaod() { return canDownlaod; } public void setCanDownlaod(Boolean canDownlaod) { this.canDownlaod = canDownlaod; } public Boolean getCanUpdate() { return canUpdate; } public void setCanUpdate(Boolean canUpdate) { this.canUpdate = canUpdate; } public String getIpAdd() { return ipAdd; } public void setIpAdd(String ipAdd) { this.ipAdd = ipAdd; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getPathDir() { return pathDir; } public void setPathDir(String pathDir) { this.pathDir = pathDir; } public String getPort() { return port; } public void setPort(String port) { this.port = port; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } }
public class ClientInfo { private String ipAdd; private int port; private Boolean loginState = false; private String localPath = "D:/FTPClient/"; private String currentPath; private String currentServerPath; public String getIpAdd() { return ipAdd; } public void setIpAdd(String ipAdd) { this.ipAdd = ipAdd; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public Boolean getLoginState() { return loginState; } public void setLoginState(Boolean loginState) { this.loginState = loginState; } public String getLocalPath() { return localPath; } public void setLocalPath(String localPath) { this.localPath = localPath; } public String getCurrentPath() { currentPath = localPath; return currentPath; } public void setCurrentPath(String currentPath) { this.currentPath = currentPath; } public String getCurrentServerPath() { return currentServerPath; } public void setCurrentServerPath(String currentServerPath) { this.currentServerPath = currentServerPath; }
(代码见附件)
// 从流中读取内容并保存 private void readAndSave(InputStream is) throws IOException { String filename = getFileName(is); int file_len = readInteger(is); System.out.println("接收文件:" + filename + ",长度:" + file_len); readAndSave0(is, savePath + filename, file_len); System.out.println("文件保存成功(" + file_len + "字节)。"); } private void readAndSave0(InputStream is, String path, int file_len) throws IOException { FileOutputStream os = getFileOS(path); readAndWrite(is, os, file_len); os.close(); } // 边读边写,直到读取 size 个字节 private void readAndWrite(InputStream is, FileOutputStream os, int size) throws IOException { byte[] buffer = new byte[4096]; int count = 0; while (count < size) { int n = is.read(buffer); // 这里没有考虑 n = -1 的情况 os.write(buffer, 0, n); count += n; } } // 读取文件名 private String getFileName(InputStream is) throws IOException { int name_len = readInteger(is); byte[] result = new byte[name_len]; is.read(result); return new String(result); } // 读取一个数字 private int readInteger(InputStream is) throws IOException { byte[] bytes = new byte[4]; is.read(bytes); return b2i(bytes); } // 创建文件并返回输出流 private FileOutputStream getFileOS(String path) throws IOException { File file = new File(path); if (!file.exists()) { file.createNewFile(); } return new FileOutputStream(file); }
(见附件)
(未完待续)