.Net下载共享文件夹中的文件

发布于:2025-08-07 ⋅ 阅读:(9) ⋅ 点赞:(0)

由于IIS站点权限等问题,总是没找到处理办法,所以改用外挂的winform的方式来下载共享文件(也可以改为使用windows服务的方式)。
前提需要先在资源管理器中登录到共享文件夹,确保系统能访问。

  1. 服务端代码 (.NET后端)
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Web;

public class FileDownloadService
{
    private const int WinFormPort = 11000;

    public void DownloadFile(string filePath)
    {
        try
        {
            // 1. 连接到WinForm客户端
            using (TcpClient client = new TcpClient("127.0.0.1", WinFormPort))
            using (NetworkStream netStream = client.GetStream())
            {
                // 2. 发送文件路径
                byte[] pathData = Encoding.UTF8.GetBytes(filePath);
                netStream.Write(pathData, 0, pathData.Length);

                // 3. 设置响应头
                Response.Clear();
                Response.ContentType = "application/octet-stream";
                Response.AddHeader("Content-Disposition", 
                                 $"attachment; filename={HttpUtility.UrlEncode(Path.GetFileName(filePath))}");
                
                // 4. 流式传输到客户端浏览器
                byte[] buffer = new byte[1024 * 1024]; // 1MB缓冲区
                int bytesRead;
                while ((bytesRead = netStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    Response.OutputStream.Write(buffer, 0, bytesRead);
                    Response.Flush();
                }
            }
        }
        catch (Exception ex)
        {
            Response.Write($"下载错误: {ex.Message}");
        }
        finally
        {
            Response.End();
        }
    }
}
  1. WinForm客户端代码
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;

public class FileTransferService : IDisposable
{
    private TcpListener _listener;
    private const int Port = 11000;
    private bool _isRunning;

    public void Start()
    {
        _isRunning = true;
        _listener = new TcpListener(IPAddress.Loopback, Port);
        _listener.Start(10); // 允许10个等待连接
        BeginAcceptClient();
    }

    private void BeginAcceptClient()
    {
        if (_isRunning)
        {
            _listener.BeginAcceptTcpClient(ClientHandler, null);
        }
    }

    private void ClientHandler(IAsyncResult ar)
    {
        TcpClient client = null;
        try
        {
            client = _listener.EndAcceptTcpClient(ar);
            ThreadPool.QueueUserWorkItem(ProcessClient, client);
        }
        catch (Exception ex)
        {
            client?.Dispose();
            MessageBox.Show($"接受连接错误: {ex.Message}");
        }
        finally
        {
            BeginAcceptClient(); // 继续监听新连接
        }
    }

    private void ProcessClient(object state)
    {
        using (TcpClient client = (TcpClient)state)
        {
            try
            {
                client.SendTimeout = 30000; // 30秒发送超时
                client.ReceiveTimeout = 30000; // 30秒接收超时

                using (NetworkStream netStream = client.GetStream())
                {
                    // 1. 接收文件路径
                    byte[] buffer = new byte[1024];
                    int received = netStream.Read(buffer, 0, buffer.Length);
                    string filePath = Encoding.UTF8.GetString(buffer, 0, received);

                    // 2. 检查文件是否存在
                    if (!File.Exists(filePath))
                    {
                        byte[] error = Encoding.UTF8.GetBytes("FILE_NOT_FOUND");
                        netStream.Write(error, 0, error.Length);
                        return;
                    }

                    // 3. 分块读取文件并传输
                    using (FileStream fs = File.OpenRead(filePath))
                    {
                        byte[] fileBuffer = new byte[1024 * 1024]; // 1MB缓冲区
                        int bytesRead;
                        while ((bytesRead = fs.Read(fileBuffer, 0, fileBuffer.Length)) > 0)
                        {
                            netStream.Write(fileBuffer, 0, bytesRead);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                try
                {
                    byte[] error = Encoding.UTF8.GetBytes($"ERROR:{ex.Message}");
                    client.GetStream().Write(error, 0, error.Length);
                }
                catch { /* 忽略二次错误 */ }
            }
        }
    }

    public void Stop()
    {
        _isRunning = false;
        _listener?.Stop();
    }

    public void Dispose()
    {
        Stop();
        _listener?.Dispose();
    }
}
  1. WinForm界面
public partial class MainForm : Form
{
    private FileTransferService _fileService;

    public MainForm()
    {
        InitializeComponent();
        _fileService = new FileTransferService();
        _fileService.Start();
    }

    protected override void OnFormClosing(FormClosingEventArgs e)
    {
        _fileService.Dispose();
        base.OnFormClosing(e);
    }

    private void btnStart_Click(object sender, EventArgs e)
    {
        _fileService.Start();
        lblStatus.Text = "服务已启动 (端口:11000)";
    }

    private void btnStop_Click(object sender, EventArgs e)
    {
        _fileService.Stop();
        lblStatus.Text = "服务已停止";
    }
}

Windows查看端口是否被占用

netstat -ano | findstr "端口号"

网站公告

今日签到

点亮在社区的每一天
去签到