一、适用场景
我们平时习惯了使用ftp来上传下载文件,尤其是很多Linux环境下,我们一般都会通过第三方的SSH工具连接到Linux,但是当我们需要传输文件到Linux服务器当中,很多人习惯用ftp来传输,其实Linux默认是不提供ftp的,需要你额外安装FTP服务器。而且ftp服务器端会占用一定的VPS服务器资源。其实笔者更建议使用sftp代替ftp。
主要因为:
一、可以不用额外安装任何服务器端程序。
二、会更省系统资源。
三、SFTP使用加密传输认证信息和传输数据,相对来说会更安全。
四、也不需要单独配置,对新手来说比较简单(开启SSH默认就开启了SFTP)。
二、主要区别
FTP是一种文件传输协议,一般是为了方便数据共享的。包括一个FTP服务器和多个FTP客户端。FTP客户端通过FTP协议在服务器上下载资源。
而SFTP协议是在FTP的基础上对数据进行加密,使得传输的数据相对来说更安全。但是这种安全是以牺牲效率为代价的,也就是说SFTP的传输效率比FTP要低(不过现实使用当中,没有发现多大差别)。个人肤浅的认为就是:一;FTP要安装,SFTP不要安装。二;SFTP更安全,但更安全带来副作用就是的效率比FTP要低些。
三 本次讲解,私钥公钥问题
本次重点讲解sftp,跟据公司要求,这次做了一个sftp,sftp很多都是通过< ip,用户名,密码> 但是这次遇到一个问题,那么就是使用公钥,跟私钥的方式:进行访问服务器, 不太会写文字,描述,直接上程序
秘钥支持:BEGI 之后跳过两个字节 后跟DSA或者RSA或者SSH 如果有这几个的才支持,别的应该不持之,可以试一下
原本想把项目贴进来呢,回想了一下,发现我不会,如果想要sftp整个项目的可以加我QQ,ftp也有 1649514562
首先引用三个dll
string result; SFTPClass sftp = ToolsService.ConnSFTP("/download/", out result);//最小路径,也属于服务器已经存在的主目录 //链接上传 sftp.Connect(); //判断服务器文件夹是否存在
if (sftp.DirExist("/telSale/") == false) {
//创建文件夹 sftp.CreateDirectory("/telSale/"); } if (sftp.DirExist("/telSale/" + DateTime.Now.ToString("yyyyMMdd") + "/") == false) { //一级一级的创建 sftp.CreateDirectory("/telSale/" + DateTime.Now.ToString("yyyyMMdd") + "/"); } if (sftp.DirExist("/telSale/" + DateTime.Now.ToString("yyyyMMdd") + "/insPolicy/") == false) { sftp.CreateDirectory("/telSale/" + DateTime.Now.ToString("yyyyMMdd") + "/insPolicy/"); } //上传 sftp.Put("D:\sftp_put\insPolicy.txt");//全文件名 文件支持各种格式 sftp.Disconnect(); //-----------------------下载----------------------------------------- //链接 SFTPClass sftpx = ToolsService.ConnSFTP("/upload/telSale /" + DateTime.Now.ToString("yyyyMMdd") + "/insPolicy/", out result);//最小路径,也属于服务器已经存在的主目录 sftpx.Connect(); sftpx.Get("insPolicy.txt", "D:\sftp_put\upload");//第一个服务器文件名,第二个下载到哪里 sftpx.Disconnect();
/// <summary> /// 连接SFTP,自动获取app.xml中的指定配置,创建好一个sftp /// sftp在使用操作前需要调用Connect方法,在不需要的时候要使用DisConnect,中间过程不需要断开连接 /// </summary> /// <param name="ftpname">app.xml中配置的ftp名称</param> /// <param name="remotePath">FTP上的路径,不包含文件名,初始化的时候设置,一次连接长期使用.</param> /// <returns>创建成功,则返回SFTP实例</returns> public static SFTPClass ConnSFTP(string remotePath, out string errorMsg) { errorMsg = ""; try { //采用ip跟用户名,公钥私钥的方式访问sftp,密码传递空,如果使用密码方式,要传递密码,私钥公钥方式可去除 string url = "211.101.11.33"; string username = "trade_name"; string password = null; SFTPClass sftp = new SFTPClass(url, username, password, remotePath); return sftp; } catch (Exception e) { errorMsg = e.Message; return null; } }
using System; using System.Text; using Tamir.SharpSsh.jsch; namespace Tms.Utils { public class SFTPClass { private Session m_session; private Channel m_channel; private ChannelSftp m_sftp; private string remotePath = "/";//FTP上的路径,不包含文件名,路径应为"/" //private Tamir.SharpSsh.jsch.examples.Sftp.MyProgressMonitor m_monitor; private static readonly string defRemotePath = "/download/";//默认操作是都是从根目录开始。 /// <summary> /// 实例化SFTP, 用于创建连接对象 /// </summary> /// <param name="host">sftp IP地址</param> /// <param name="user">用户名</param> /// <param name="pwd">密码</param> /// <param name="ftpPath">FTP上的路径</param> public SFTPClass(string host, string user, string pwd, string ftpPath) { string[] arr = host.Split(':'); string ip = arr[0]; int port = 20000;//端口号替换 if (arr.Length > 1) port = Int32.Parse(arr[1]); JSch jsch = new JSch(); jsch.addIdentity("D:\MTS-SFTP\Privite-Key\Identity");//将私钥配置在客户端,这个配置的是私钥,公钥配置在了服务端 m_session = jsch.getSession(user, ip, port); MyUserInfo ui = new MyUserInfo(); ui.setPassword(pwd); m_session.setUserInfo(ui); if (!string.IsNullOrEmpty(ftpPath)) this.remotePath = ftpPath; } /// <summary> /// SFTP连接状态 /// </summary> public bool Connected { get { return m_session.isConnected(); } } /// <summary> /// 连接SFTP /// </summary> /// <returns></returns> public bool Connect() { if (!Connected) { m_session.connect(); m_channel = m_session.openChannel("sftp"); m_channel.connect(); m_sftp = (ChannelSftp)m_channel; } return true; } /// <summary> /// 断开SFTP /// </summary> public void Disconnect() { if (Connected) { m_channel.disconnect(); m_session.disconnect(); } } /// <summary> /// 向SFTP存放文件 /// </summary> /// <param name="localPath">要上传FTP的文件全路径,包含文件名</param> /// <returns></returns> public bool Put(string localPath) { string path = "/download/telSale/" + DateTime.Now.ToString("yyyyMMdd") + "/insPolicy/"; Tamir.SharpSsh.java.String src = new Tamir.SharpSsh.java.String(localPath); Tamir.SharpSsh.java.String dst = new Tamir.SharpSsh.java.String(path); m_sftp.put(src, dst); return true; } /// <summary> /// SFTP获取文件 /// </summary> /// <param name="filename">FTP上的文件名,不需要包含路径</param> /// <param name="localPath">保存放文件的本地路径</param> /// <returns></returns> public bool Get(string filename, string localPath) { Tamir.SharpSsh.java.String src = new Tamir.SharpSsh.java.String(this.remotePath + filename); Tamir.SharpSsh.java.String dst = new Tamir.SharpSsh.java.String(localPath); //m_sftp.get(src, dst, m_monitor, ChannelSftp.OVERWRITE); m_sftp.get(src, dst); return true; } /// <summary> /// 删除SFTP上的文件 /// </summary> /// <param name="fileName"></param> /// <returns></returns> public bool Delete(string fileName) { m_sftp.rm(this.remotePath + fileName); return true; } /// <summary> /// 目录是否存在 /// </summary> /// <param name="dirName">目录名称必须从根开始</param> /// <returns></returns> public bool Exist(string dirName) { m_sftp.ls(dirName); return true; } /// <summary> /// 判断目录是否存在 建议使用这个 /// </summary> /// <param name="dirName"></param> /// <returns></returns> public bool DirExist(string dirName) { try { m_sftp.ls(defRemotePath + dirName.Trim()); return true; } catch (Tamir.SharpSsh.jsch.SftpException) { return false;//执行ls命令时出错,则目录不存在。 } } /// <summary> /// 创建目录 /// </summary> /// <param name="dirName">目录名称必须从根开始</param> /// <returns></returns> public void CreateDirectory(string dirName) { bool isExist = false; Tamir.SharpSsh.java.util.Vector vvv = m_sftp.ls(defRemotePath); foreach (Tamir.SharpSsh.jsch.ChannelSftp.LsEntry fileName in vvv) { string name = fileName.getFilename(); if (name == dirName.Trim('/')) { isExist = true; } } if (!isExist) { m_sftp.mkdir(defRemotePath + dirName.Trim()); } } /// <summary> /// 获取SFTP文件名称列表 /// </summary> /// <param name="remotePath">SFTP路径</param> /// <returns></returns> public string[] GetFileList() { try { Tamir.SharpSsh.java.util.Vector vector = m_sftp.ls(this.remotePath); StringBuilder fileNames = new StringBuilder(); foreach (Tamir.SharpSsh.jsch.ChannelSftp.LsEntry q in vector) { string fileName = q.getFilename(); fileNames.Append(fileName); fileNames.Append(" "); } fileNames.Remove(fileNames.ToString().LastIndexOf(' '), 1); return fileNames.ToString().Split(' '); ; } catch { this.Disconnect(); return null; } } //登录验证信息 public class MyUserInfo : UserInfo { String passwd; public String getPassword() { return passwd; } public void setPassword(String passwd) { this.passwd = passwd; } public String getPassphrase() { return null; } public bool promptPassphrase(String message) { return true; } public bool promptPassword(String message) { return true; } public bool promptYesNo(String message) { return true; } public void showMessage(String message) { } } } }