由于IIS站点权限等问题,总是没找到处理办法,所以改用外挂的winform的方式来下载共享文件(也可以改为使用windows服务的方式)。
前提需要先在资源管理器中登录到共享文件夹,确保系统能访问。
- 服务端代码 (.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();
}
}
}
- 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();
}
}
- 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 "端口号"