博客
关于我
nft文件传输_利用remoting实现文件传输-.NET教程,远程及网络应用
阅读量:789 次
发布时间:2023-02-15

本文共 15257 字,大约阅读时间需要 50 分钟。

为了实现文件传输功能,我们使用 System.Runtime.Remoting 框架,通过定义接口和实现相应的类来完成文件的传输和校验。以下是完整的代码实现:

using System;using System.Runtime;using System.Runtime.Remoting;using System.Runtime.Remoting.Channels;using System.Runtime.Remoting.Channels.TCP;using System.IO;namespace Nail.Net.Remoting.Trans{    public interface ITransFile    {        int SendFile(string filename, byte[] bytes, int clientCrc);        bool CompareFile(string filename, int clientCrc);        int GetFileDet(string filename);        int GetFileInfo(string filename);        byte[] GetFileInfo(string filename, int length);        byte[] GetFileInfo(string filename, int point, int length);        string ServerSaveFilePath { get; set; }        string ServerTempFilePath { get; set; }    }    public class FileTransClient    {        private int _tranTemSize = 1024;        private int _tranType = 1;        private int _tranPort = 10001;        private string _tranServerName = "localhost";        private int _tranCrc32 = 0;        private ITransFile _tranServer;        private Timer _timer;        private FrmTransfersUI _ui;        private string _fullFileName;        public string FullFileName        {            get => _fullFileName;            set => _fullFileName = value;        }        public int TemSize        {            get => _tranTemSize;            set => _tranTemSize = value;        }        public int Port        {            get => _tranPort;            set => _tranPort = value;        }        public string ServerName        {            get => _tranServerName;            set => _tranServerName = value;        }        public int Type        {            get => _tranType;            set => _tranType = value;        }        public int Crc32        {            get => _tranCrc32;            set => _tranCrc32 = value;        }        public bool CompareFile(string filename, int clientCrc)        {            byte[] fileData = GetFileInfo(filename);            using (Crc32 _crc = new())            {                return _crc.CalculateFile(filename);            }        }        public void ConnectServer()        {            try            {                switch (_tranType)                {                    case TrType.TCP:                    {                        _tranServer = (ITransFile)Activator.GetObject(typeof(ITransFile), $"tcp://{_tranServerName}:{_tranPort}/ {_tranServerName}");                        break;                    }                    case TrType.HTTP:                    {                        _tranServer = (ITransFile)Activator.GetObject(typeof(ITransFile), $"http://{_tranServerName}:{_tranPort}/ {_tranServerName}");                        break;                    }                }            }            catch (Exception ex)            {                MessageBox.Show(ex.ToString());            }        }        public byte[] GetFileInfo(string filename)        {            using (FileStream _fileStream = new(filename, FileMode.Open, FileAccess.Read, FileShare.Read))            {                return _fileStream.ReadAllBytes();            }        }        public void SendFile()        {            _ui.Show();            _timer.Interval = 1000;            _timer.Start();            Thread _thread = new(OnSendFile, this);            _thread.Start();        }        private void OnSendFile()        {            try            {                int _currentCrc = CheckFileInfo(_fullFileName);                byte[] _fileBytes = GetFileInfo(_fullFileName);                if (_fileBytes.Length == 0)                {                    MessageBox.Show("这是一个空文件,无法传输!");                    return;                }                int _totalSize = _fileBytes.Length;                int _fileNameLength = _fullFileName.Length;                int _crc = _currentCrc;                byte[] _buffer = new byte[_tranTemSize - 1];                using (FileStream _fileStream = new(_fullFileName, FileMode.Open, FileAccess.Read, FileShare.Read))                {                    int _current = 0;                    int _totalBlocks = (int)_totalSize / _tranTemSize;                    int _currentBlock = 0;                    _ui.RateOfProgress = 0;                    _ui.PercentOfProgress = "0%";                    _ui.LeaveTime = "完成";                    _ui.TransEd = "0 byte";                    while (_current < _totalSize)                    {                        int _readSize = (int)Math.Min(_tranTemSize, _totalSize - _current);                        _ui.RateOfProgress = _readSize;                        _ui.PercentOfProgress = (int)((_current + _readSize) / _totalSize * 100).ToString() + "%";                        int _block = _current / _tranTemSize + 1;                        if (_block != _currentBlock)                        {                            _ui.LeaveTime = timespan.FromSeconds((int)((_totalSize - _current) / _tranTemSize) / (int)_tranTemSize).ToString();                        }                        if (_ui.BtnCancel.Text == "确定")                        {                            _ui.Close();                        }                        _current += _readSize;                        _ui.RateOfTransfers = (int)_readSize / _tranTemSize;                        using (MemoryStream _memStream = new())                        {                            BinaryWriter _bw = new(_memStream);                            for (int i = 0; i < _readSize; i++)                            {                                _bw.Write(_fileBytes[_current + i]);                            }                            _bw.Flush();                            _memStream.Flush();                            byte[] _data = _memStream.ToArray();                            _tranServer.SendFile(_fullFileName, _data, _crc);                        }                    }                }            }            catch (Exception ex)            {                MessageBox.Show(ex.ToString());            }            finally            {                _timer.Stop();                _ui.Close();            }        }        private void Timer1_Tick(object sender, EventArgs e)        {            _tranCrc32++;        }        public void ShowUI()        {            _ui = new FrmTransfersUI();            _ui.Show();        }    }    public class FrmTransfersUI : Form    {        private readonly Label _lblRateOfTransfers;        private readonly Label _lblTransfersFileName;        private readonly Button _btnCancel;        private readonly Label _lblFileSize;        private readonly Label _lblLeaveTime;        private readonly Label _lblPercentOfProgress;        private readonly Label _lblTransed;        private readonly ProgressBar _pgbTransfers;        private readonly Button _btnPause;        private readonly Timer _timer;        public FrmTransfersUI()        {            InitializeComponent();        }        protected override void Dispose(bool disposing)        {            if (disposing && components != null)            {                components.Dispose();            }            base.Dispose(disposing);        }        private void initializeComponent()        {            button1 = new Button();            pgbTransfers = new ProgressBar();            button2 = new Button();            lblRateOfTransfers = new Label();            lblTransed = new Label();            lblTransfersFileName = new Label();            btnCancel = new Button();            lblFileSize = new Label();            lblLeaveTime = new Label();            lblPercentOfProgress = new Label();            components.Add(lblFileSize);            components.Add(lblLeaveTime);            components.Add(lblPercentOfProgress);            components.Add(btnCancel);            components.Add(lblTransfersFileName);            components.Add(lblTransed);            components.Add(lblRateOfTransfers);            components.Add(pgbTransfers);            components.Add(button2);            components.Add(button1);        }        public event Action userCancel;        public event Action
RateOfTransfersChanged; public event Action
TransfersFileNameChanged; public event Action
FileSizeChanged; public event Action
LeaveTimeChanged; public event Action
PercentOfProgressChanged; public event Action
TransedChanged; public event Action
RateOfTransfersUpdated; private int _current = 0; private int _total = 0; private int _blockSize = 1024; private bool _isPaused = false; public override void HandleDestroyed() { if (!isDisposed) { components.Dispose(); } base.HandleDestroyed(); } public override bool ShowDialog() { if (recreateHandle && !IsVisible) { recreateHandle = false; CreateControl(); Initialize(); } return base.ShowDialog(); } public override bool StartPositionFormShow = false; public override FormStartPosition GetPositionDialog = FormStartPosition.CenterScreen; public override bool ShowInTaskBar = false; public override int FormBorderStyle = FormBorderStyle.None; public override string Text = "文件传输进度"; public override bool MaximizeBox = false; public int MaxOfProgress { set => _pgbTransfers.Maximum = value; } public int RateOfProgress { set => _pgbTransfers.Value = value; } public int RateOfTransfers { set => _lblRateOfTransfers.Text = "传输速度: " + value; } public int Transed { set => _lblTransed.Text = "已传送: " + value; } public string TransfersFileName { set => _lblTransfersFileName.Text = "传输文件: " + value; } public int PercentOfProgress { set => _lblPercentOfProgress.Text = "传输进度: " + value; } public string LeaveTime { set => _lblLeaveTime.Text = "剩余时间: " + value; } public string FileSize { set => _lblFileSize.Text = "文件大小: " + value; } private void button1_Click(object sender, EventArgs e) { if (isPaused) { _current = _total; _isPaused = false; button1.Text = "暂停"; } else { _isPaused = true; button1.Text = "继续"; } } private void button2_Click(object sender, EventArgs e) { if (userCancel != null) { userCancel(); } } private void Timer1_Tick(object sender, EventArgs e) { if (_isPaused) { return; } _current += _blockSize; _total += _blockSize; _pgbTransfers.Value = _current; _lblPercentOfProgress.Text = (int)((_current / _total) * 100).ToString() + "%"; _lblFileSize.Text = $"{_total / 1024} KB"; int _remaining = _total - _current; if (_remaining == 0) { _lblLeaveTime.Text = "完成"; button1.Text = "确定"; } else { int _seconds = (int)Math.Ceiling(_remaining / _tranTemSize); _lblLeaveTime.Text = $"{_seconds}秒"; } _lblTransed.Text = $"{_current / 1024} KB"; RateOfTransfersUpdated?.Invoke(Math.Max(0, (int)((_current / _tranTemSize) * 1024) / _tranTemSize).ToString() + " KB/秒")); } public void Close() { _ui?.Dispose(); if (components != null) { components.Dispose(); } base.Close(); } } public enum TrType { TCP = 1, HTTP = 2 } public class FileTransServer : MarshalByRefObject { private int _tranType = 1; private int _tranPort = 10001; private string _tranServerName = "localhost"; private int _tranCrc32 = 0; private string _tranTempFilePath = "f:\\"; private string _tranSaveFilePath = "e:\\"; private string _tranFileName = ""; public int Type { get => _tranType; set => _tranType = value; } public int Port { get => _tranPort; set => _tranPort = value; } public string ServerName { get => _tranServerName; set => _tranServerName = value; } public string TempFilePath { get => _tranTempFilePath; set => _tranTempFilePath = value; } public string SaveFilePath { get => _tranSaveFilePath; set => _tranSaveFilePath = value; } public override void InitializeLifetimeService() { ThreadPool.QueueUserWork(() => RemotingConfigure.ApplicationName = this.GetType().Name); } public int StartServer() { try { switch (_tranType) { case TrType.TCP: { var _channel = new TCPChannel(_tranPort); ChannelServices.RegisterChannel(_channel); break; } case TrType.HTTP: { var _channel = new HTTPChannel(_tranPort); ChannelServices.RegisterChannel(_channel); break; } } RemotingConfiguration.RegisterWellKnownServiceType(typeof(FileTransFile), this.GetType().Name, WellKnownObjectMode.SingleCall); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } return 0; } } public class FileTransFile : MarshalByRefObject, ITransFile { private string _tempFilePath = "f:\\"; private string _saveFilePath = "e:\\"; private byte[] _fileBytes; public int SendFile(string filename, byte[] bytes, int clientCrc) { try { using (FileStream _fileStream = new(_tempFilePath + filename, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) { _fileStream.Seek(_fileStream.Length, SeekOrigin.Begin); _fileStream.Write(bytes, 0, bytes.Length); } File.Delete(_tempFilePath + filename); if (CompareFile(_tempFilePath + filename, clientCrc)) { File.Copy(_tempFilePath + filename, _saveFilePath + filename, true); } else { File.Delete(_tempFilePath + filename); } return 0; } catch (Exception ex) { MessageBox.Show(ex.ToString()); return 1; } finally { if (!File.Exists(_tempFilePath + filename)) { File.Delete(_tempFilePath + filename); } } } public bool CompareFile(string filename, int clientCrc) { byte[] fileData = GetFileInfo(filename); using (Crc32 _crc = new()) { return _crc.CalculateFile(filename); } } public int GetFileDet(string filename) { using (FileStream _fileStream = new(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) { return _fileStream.Length; } } public byte[] GetFileInfo(string filename) { using (FileStream _fileStream = new(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) { return _fileStream.ReadAllBytes(); } } public int GetFileInfo(string filename, int length) { return GetFileInfo(filename, 0, length); } public byte[] GetFileInfo(string filename, int point, int length) { using (FileStream _fileStream = new(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) { _fileStream.Seek(point, SeekOrigin.Begin); byte[] _buffer = new byte[length - 1]; _fileStream.Read(_buffer, 0, length); return _buffer; } } } public class TrType { public const int TCP = 1; public const int HTTP = 2; } public class FileTransClientConfig { public int TemSize { get; set; } = 1024; public int Port { get; set; } = 10001; public string ServerName { get; set; } = "localhost"; public int Type { get; set; } = TrType.TCP; public int Crc32 { get; set; } = 0; }}

使用方法:

服务器端:

var server = new FileTransServer();server.ServerName = "aaa";server.Port = 10001;server.Type = FileTransServer.TrType.HTTP;server.TempFilePath = "f:\\";server.SaveFilePath = "e:\\";server.StartServer();

客户端:

var client = new FileTransClient();client.Port = 10001;client.ServerName = "aaa";client.TemSize = 1024;client.FullFileName = "c:\\111.rar";client.Type = FileTransClientConfig.TrType.HTTP;client.ConnectServer();client.SendFile();

功能说明:

  • 文件传输:客户端通过 SendFile 方法将文件发送到服务器,服务器端接收后存储到指定路径。
  • 进度条:客户端显示实时传输进度,包括文件大小、传输速度和剩余时间。
  • CRC32校验:在传输过程中使用CRC32校验文件完整性,确保传输的文件完整无误。
  • 暂停/继续:支持暂停和继续传输功能,用户可以根据需要中断传输。
  • 依赖项:

    确保在项目中引入以下 namespaces:

    服务器配置:

    • 端口:指定服务器监听的端口。
    • 服务器名称:服务器的名称或IP地址。
    • 传输类型:选择TCP或HTTP协议。
    • 临时文件路径:用于存储临时传输的文件。
    • 保存文件路径:存储最终传输完成的文件。

    客户端配置:

    • 端口:与服务器端配置的端口一致。
    • 服务器名称:服务器的名称或IP地址。
    • 传输块大小:决定传输块的大小。
    • 传输类型:选择TCP或HTTP协议。
    • 文件路径:指定要传输的文件路径。

    通过以上代码实现,您可以轻松完成文件的分布式传输和校验功能,同时提供友好的用户界面和实时传输进度反馈。

    转载地址:http://pacfk.baihongyu.com/

    你可能感兴趣的文章
    NFS网络文件系统
    查看>>
    NFS远程目录挂载
    查看>>
    nft文件传输_利用remoting实现文件传输-.NET教程,远程及网络应用
    查看>>
    NFV商用可行新华三vBRAS方案实践验证
    查看>>
    ng build --aot --prod生成文件报错
    查看>>
    ng 指令的自定义、使用
    查看>>