SMB协议实现局域网之间文件传输

发布时间 2023-07-30 14:45:38作者: 一样的梦

一、背景

为解决历史资料存储位置分散(局域网不同服务器),管理人员众多,资料管理仍保留在传统ftp管理阶段等问题,开展对历史资料管理功能,具体需求功能因为保密协议就不在阐述,本次只针对技术局域网之间传输技术进行讨论

二、技术对比

访问局域网中共享信息有两种方式,网络映射、SMB协议访问,这两种都是比较成熟的技术了。

 

序号

指标

网络映射

SMB协议

1

传输

速度

传输效率主要跟局域网网络传输效率有关,传输效率快。

在文件传输过程中,创建文件会导致高协议开销和较高的文件系统开销。 对于大型文件传输,这些成本仅出现一次。 当传输大量小文件时,成本是重复的,导致传输速度缓慢;

2

第一次访问

必须在本地创建映射

通过用户名、密码直接可以访问

3

访问人数

无限制

无限制

4

系统兼容性

兼容windows、Linux系统

SMB协议只能在windows系统之间传输,如果是Linux主机,需要对linux主机安装Samba

5

传输是否加密

加密

加密

6

安全性

如果在一台服务器映射多个磁盘会有安全隐患;不能创建同一个ip下的不通共享目录

局域网内所有电脑都可以通过smb协议进行访问,有安全隐患。

 

 

三、SMB协议介绍

 

 

SMB(Server Message Block)是由微软开发的一种软件程序级的网络传输协议,主要用来使得一个网络上的计算机共享计文件、打印机、串行端口和通信等资源。它也提供认证的进行进程间通讯机能。通过Unix服务器厂商从新开发后,它能够用于链接Unix服务器和Windows客户机,执行打印和文件共享等任务。

  SMB一开始的设计是在NetBIOS协议上运行的(而NetBIOS自己则运行在NetBEUI、IPX/SPX或TCP/IP协议上)。从Windows2000开始,微软引入SMB Direct Over TCP,从新命名为 CIFS(Common Internet File System),并打算将它与NetBIOS相脱离,试图使它成为Internet上计算机之间相互共享数据的一种标准。CIFS是公开或开放的SMB协议版本。s

 

四、SMB协议实现常用功能

参考的:https://www.cjavapy.com/article/395/

基础环境:.net 4.5以上   

smb包:SharpCifs.Core,

(1)windows创建共享目录

创建共享目录这块不是重点,可参考如下网站:

https://jingyan.baidu.com/article/0bc808fc1f06765ad485b987.html

(2)SMB协议连接共享目录

        /// <summary>

        /// 测试连接是否通

        /// </summary>

        /// <param name="returnMessag"></param>

        /// <param name="ip"></param>

        /// <param name="name"></param>

        /// <param name="pwd"></param>

        /// <param name="folder"></param>

        /// <returns></returns>

        public bool GetCon(string ip, string name, string pwd, string folder)

        {

            SharpCifs.Config.SetProperty("jcifs.smb.client.lport", "8137");

            var auth2 = new NtlmPasswordAuthentication(ip, name, pwd);

            SmbFile outDirFile = new SmbFile("smb://" + ip + "/" + folder + "/", auth2);

            bool returnMessag = outDirFile.Exists();

            return returnMessag;

        }

(3)通过SMB协议获取文件信息

     #region 获取文档信息,这块使用了递归

 

 

        /// <summary>

        /// 获取文档信息

        /// </summary>

        /// <param name="liststring"></param>

        /// <param name="ip_folder"></param>

        /// <param name="name"></param>

        /// <param name="pwd"></param>

        /// <param name="ip"></param>

        public void getListString(List<FileClass> liststring, string ip_folder, string name, string pwd, string ip, string parentdocid)

        {

            SmbFile outDirFile = new SMBClass().GetSmbFile(ip_folder, name, pwd, ip);

            var epocDate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

            string msg = "";

            foreach (SmbFile item in outDirFile.ListFiles())

            {

                try

                {

                    FileClass files = new FileClass();

                    files.IsFileDoc = false;

                    var type = item.IsFile() ? "file" : "dir";

                    var filename = "";// item.GetName();//文件名称

                    if (type == "dir")

                    {

                        filename = FilesClass.getFiles(item.ToString(), type);

                        files.IsFileDoc = true;

                        files.FileSize = 0;

                    }

                    else

                    {

                        filename = FilesClass.getFiles(item.ToString(), type);

                        files.FileSize = item.Length();

                        files.DocFileType = FilesClass.getFileExt(filename);

                    }

                    DateTime tm = item.GetLocalCreateTime();

                    files.CreationDate = tm;

                    files.DocName = filename;

                    files.DocID = Guid.NewGuid().ToString().Trim();

                    files.DocType = 2;

                    files.ParentDocid = parentdocid;

                    files.DocFileNameWithPath = item.ToString().Replace("%23", "#");

                    files.FileFullPath = item.ToString().Replace("smb://" + ip + "/", "").Replace("%23", "#");///文档全路径,解决特殊字符问题;

                    liststring.Add(files);

 

                    if (type == "dir")

                    {

                        getListString(liststring, item.ToString(), name, pwd, ip, files.DocID);///递归循环

                    }

                }

                catch (Exception ex)

                {

                   /// new NoteClass().WriteNoteToTxt("错误:" + ex.Message);                

}

 

            }

 

        }

        #endregion

 

(4)通过SMB协议判断文件是否存在、删除文件信息

调用方法:

  SmbFile file = new SMBClass().GetSmbFile(filepyth, username, pwd, ip);//获取SMBfiles

  bool returnMessag = file.Exists();

  if (returnMessag) {file.Delete();}

        /// <summary>

        /// 获取文件信息

        /// </summary>

        /// <param name="returnMessag"></param>

        /// <param name="ip_folder"></param>

        /// <param name="name"></param>

        /// <param name="pwd"></param>

        /// <param name="folder"></param>

        /// <returns></returns>

        public SmbFile GetSmbFile(string ip_folder, string name, string pwd, string ip)

        {

            SharpCifs.Config.SetProperty("jcifs.smb.client.lport", "8137");

            NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(ip, name, pwd);

            ip_folder = ip_folder.Replace("#", "%23");//特殊字符处理

            Uri url = new Uri(ip_folder);

            SmbFile outDirFile = new SmbFile(url, auth);

            return outDirFile;

}

 

(5)通过SMB协议下载

 

   

   public SmbFileInputStream getsmb(string filepath, string ip, string name, string pwd)

        {

            try

            {

                var ip_folder = filepath;// "smb://192.168.1.18/wp/2.txt";///文件信息

                SmbFile file = new SMBClass().GetSmbFile(ip_folder, name, pwd, ip);//获取SMBfiles

                int length = file.GetContentLength();//得到文件的大小

                byte[] buffer = new byte[length];

                SmbFileInputStream stream = new SmbFileInputStream(file); //建立smb文件输入流

                return stream;

            }

            catch (Exception ex)

 {

                return null;

            }

        }

 

(6)通过SMB协议上传

            string url_local = @"D:\Users\Desktop\码\demo\SharpCifs.Core.dll";//本地文件

            String URL_remote = "smb://192.169.1.1/test/SharpCifs.Core.dll";//服务器文件

            ///1、创建映射

            String domainip = "192.169.1.1";///访问用户信息

            String userName = "test";//远程用户

            String passWord = "test";//密码

            String fileName = "test";///文件信息

 

            SharpCifs.Config.SetProperty("jcifs.smb.client.lport", "8137");

            var auth2 = new NtlmPasswordAuthentication(domainip, userName, passWord);

            SmbFile smbfile = new SmbFile(URL_remote, auth2);

 

 

            //2、获取本地文件路径

 

            FilePath pathes = new FilePath(url_local);

            InputStream ins = new FileInputStream(pathes);

 

 

            //3、开始上传

 

            if (smbfile.Exists())

            {

                MessageBox.Show("已存在。");

            }

            else

            {

                smbfile.Connect();

                OutputStream outs = new SmbFileOutputStream(smbfile);

                byte[] buffer = new byte[4096];

                int len = 0; //读取长度

                while ((len = ins.Read(buffer, 0, buffer.Length)) != -1)

                {

                    outs.Write(buffer, 0, len);

                }

                outs.Flush(); //刷新缓冲的输出流

                MessageBox.Show("上传完成。");

 

            }