Asp.net建立网络磁盘映射代码实现

作者:小菜 更新时间:2025-03-16 点击数:
简介:也许很多朋友在做WEB项目的时候都会碰到这样一个需求:当用户上传文件时,需要将上传的文件保存到另外一台专门的文件服务器。

要实现这样一个功能,有两种解决方案:方案

【菜科解读】

也许很多朋友在做WEB项目的时候都会碰到这样一个需求:当用户上传文件时,需要将上传的文件保存到另外一台专门的文件服务器。

要实现这样一个功能,有两种解决方案:方案一、在文件服务器上新建一站点,用来接收上传的文件,然后保存。

方案二、将文件服务器的指定目录共享给web服务器,用来保存文件。

方案一不用多说,应该是很简单的了,将上传文件的FORM表单的ACTION属性指向文件服务器上的站点即可,我们来重点说下方案二。

也许你会说,其实方案二也很简单,在WEB服务器上做下磁盘映射,然后直接访问不就行了。

其实不是这样的,IIS默认账户为NETWORK_SERVICE,该账户是没权限访问共享目录的,所以当你把站点部署到IIS上的时候,再访问映射磁盘就会报“找不到路径”的错误。

所以,直接创建磁盘映射是行不通的,我们需要在程序中用指定账户创建映射,并用该账户运行IIS进程,下面来说下详细步骤及相关代码。

1、在文件服务器上创建共享目录,并新建访问账户。

比如共享目录为:\\192.168.0.9\share访问账户为:user-1 密码为:1234562、在WEB服务器上新建用户:user-1 密码为:123456,用户组选择默认的user组即可。

3、在WEB项目中新建公共类WNetHelper01 using System.Runtime.InteropServices; 02 03 public class WNetHelper 04 { 05 [DllImport("mpr.dll", EntryPoint = "WNetAddConnection2")] 06 private static extern uint WNetAddConnection2(NetResource lpNetResource, string lpPassword, string lpUsername, uint dwFlags); 07 08 [DllImport("Mpr.dll", EntryPoint = "WNetCancelConnection2")] 09 private static extern uint WNetCancelConnection2(string lpName, uint dwFlags, bool fForce); 10 11 [StructLayout(LayoutKind.Sequential)] 12 public class NetResource 13 { 14 public int dwScope; 15 16 public int dwType; 17 18 public int dwDisplayType; 19 20 public int dwUsage; 21 22 public string lpLocalName; 23 24 public string lpRemoteName; 25 26 public string lpComment; 27 28 public string lpProvider; 29 } 30 31 /// 32 /// 为网络共享做本地映射 33 /// 34 ///

访问用户名(windows系统需要加计算机名,如:comp-1\user-1) 35 ///

访问用户密码 36 ///

网络共享路径(如:\\192.168.0.9\share) 37 ///

本地映射盘符 38 /// 39 public static uint WNetAddConnection(string username, string password, string remoteName, string localName) 40 { 41 NetResource netResource = new NetResource(); 42 43 netResource.dwScope = 2; 44 netResource.dwType = 1; 45 netResource.dwDisplayType = 3; 46 netResource.dwUsage = 1; 47 netResource.lpLocalName = localName; 48 netResource.lpRemoteName = remoteName.TrimEnd('\\'); 49 uint result = WNetAddConnection2(netResource, password, username, 0); 50 51 return result; 52 } 53 54 public static uint WNetCancelConnection(string name, uint flags, bool force) 55 { 56 uint nret = WNetCancelConnection2(name, flags, force); 57 58 return nret; 59 } 60 } 4、为IIS指定运行账户user-1要实现此功能,有两种办法:a) 在web.config文件中的节点下,添加如下配置:b) 在WEB项目中添加公用类LogonImpersonate01 public class LogonImpersonate : IDisposable 02 { 03 static public string DefaultDomain 04 { 05 get 06 { 07 return "."; 08 } 09 } 10 11 const int LOGON32_LOGON_INTERACTIVE = 2; 12 const int LOGON32_PROVIDER_DEFAULT = 0; 13 14 [System.Runtime.InteropServices.DllImport("Kernel32.dll")] 15 extern static int FormatMessage(int flag, ref IntPtr source, int msgid, int langid, ref string buf, int size, ref IntPtr args); 16 17 [System.Runtime.InteropServices.DllImport("Kernel32.dll")] 18 extern static bool CloseHandle(IntPtr handle); 19 20 [System.Runtime.InteropServices.DllImport("Advapi32.dll", SetLastError = true)] 21 extern static bool LogonUser( 22 string lpszUsername, 23 string lpszDomain, 24 string lpszPassword, 25 int dwLogonType, 26 int dwLogonProvider, 27 ref IntPtr phToken 28 ); 29 30 IntPtr token; 31 System.Security.Principal.WindowsImpersonationContext context; 32 33 public LogonImpersonate(string username, string password) 34 { 35 if (username.IndexOf("\\") == -1) 36 { 37 Init(username, password, DefaultDomain); 38 } 39 else 40 { 41 string[] pair = username.Split(new char[] { '\\' }, 2); 42 Init(pair[1], password, pair[0]); 43 } 44 } 45 public LogonImpersonate(string username, string password, string domain) 46 { 47 Init(username, password, domain); 48 } 49 void Init(string username, string password, string domain) 50 { 51 if (LogonUser(username, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token)) 52 { 53 bool error = true; 54 try 55 { 56 context = System.Security.Principal.WindowsIdentity.Impersonate(token); 57 error = false; 58 } 59 finally 60 { 61 if (error) 62 CloseHandle(token); 63 } 64 } 65 else 66 { 67 int err = System.Runtime.InteropServices.Marshal.GetLastWin32Error(); 68 69 IntPtr tempptr = IntPtr.Zero; 70 string msg = null; 71 72 FormatMessage(0x1300, ref tempptr, err, 0, ref msg, 255, ref tempptr); 73 74 throw (new Exception(msg)); 75 } 76 } 77 ~LogonImpersonate() 78 { 79 Dispose(); 80 } 81 public void Dispose() 82 { 83 if (context != null) 84 { 85 try 86 { 87 context.Undo(); 88 } 89 finally 90 { 91 CloseHandle(token); 92 context = null; 93 } 94 } 95 } 96 } 在访问映射磁盘之前首先调用此类为IIS更换运行用户:LogonImpersonate imper = new LogonImpersonate("user-1", "123456");5、在访问共享目录前,调用WNetHelper.WNetAddConnection,添加磁盘映射01 public static bool CreateDirectory(string path) 02 { 03 uint state = 0; 04 if (!Directory.Exists("Z:")) 05 { 06 state = WNetHelper.WNetAddConnection(@"comp-1\user-1", "123456", @"\\192.168.0.9\share", "Z:"); 07 } 08 if (state.Equals(0)) 09 { 10 Directory.CreateDirectory(path); 11 return true; 12 } 13 else 14 { 15 throw new Exception("添加网络驱动器错误,错误号:" + state.ToString()); 16 } 17 } 6、完成。

简洁代码就是:LogonImpersonate imper = new LogonImpersonate("user-1", "123456");WNetHelper.WNetAddConnection(@"comp-1\user-1", "123456", @"\\192.168.0.9\share", "Z:");Directory.CreateDirectory(@"Z:\newfolder");file1.SaveAs(@"Z:\newfolder\test.jpg

Asp.net,建立,网络,磁盘,映射,代码,实现,也许,

小猪教您使用tracert命令查看网络状况的方法

小伙伴们,小编今天来给你们分享一个非常劲爆的技能,那就是使用tracert命令进行查看网络故障的方法。

你们听完过后有没有心跳加快呢?要是有的话,那么,你们想不想跟小编一块去看看呢?想的话,那么事不宜迟一起去看看吧。

小伙伴你们知道tracert命令是什么吗?估计大部分的人都还不知道吧,其实tracert命令是一个检查网络状态的工具,在网络遇到问题时就可以使用这个命令进行检测各个部位的状态,来判断问题出自哪里,一一的进行排除故障。

1,用快捷键【Windows】键+【R】键,打开运行,在运行输入框中输入“cmd”并点击回车;tracert命令载图1网络状况载图22,windows命令提示符自动打开;网络状况载图33,在命令提示符中输入tracert,我们将用这个命令来查看网络问题;查看载图44,我们首先跟踪一下本机的网卡地址,tracert+空格+本机IP地址;如果跟踪不到,或者速度很慢;请检查本地网络连接,或者检查网卡问题;查看载图55,跟踪一下本地网关;tracert+空格+局域网网关地址;如果跟踪不到,请检查局域网连通性问题;tracert载图66,跟踪一个外网地址,这里我们跟踪一下百度的官网地址;如果不同,请检查internet连通性。

tracert命令载图7 查看,tracert命令,网络状况,tracert

C#开发之Socket网络编程TCP/IP层次模型、端口及报文等探讨

我们在讲解Socket编程前,先看几个和Socket编程紧密相关的概念:1、TCP/IP层次模型 当然这里我们只讨论重要的四层 01,应用层(Application):应用层是个很广泛的概念,有一些基本相同的系统级TCP/IP应用以及应用协议,也有许多的企业应用和互联网应用。

http协议在应用层运行。

02,传输层(Tanspot):传输层包括UDP和TCP,UDP几乎不对报文进行检查,而TCP提供传输保证。

03,网络层(Netwok):网络层协议由一系列协议组成,包括ICMP、IGMP、RIP、OSPF、IP(v4,v6)等。

04,链路层(Link):又称为物理数据网络接口层,负责报文传输。

然后我们来看下tcp层次模型图 从上图中可以看出,应用程序在应用层运行,在传输层,在数据前加上了TCP头,在网络层加上的IP头,在数据链路层加上了帧。

2、端口端口号范围:0-65535,总共能表示65536个数。

按端口号可分为3大类 (1)公认端口(WellKnownPorts):从0到1023,它们紧密绑定(binding)于一些服务。

通常这些端口的通讯明确表明了某种服务的协议。

例如:80端口实际上总是HTTP通讯。

(2)注册端口(RegisteredPorts):从1024到49151。

它们松散地绑定于一些服务。

也就是说有许多服务绑定于这些端口,这些端口同样用于许多其它目的。

例如:许多系统处理动态端口从1024左右开始。

(3)动态和/或私有端口(Dynamicand/orPrivatePorts):从49152到65535。

理论上,不应为服务分配这些端口。

实际上,机器通常从1024起分配动态端口。

3.TCP和UDP报文 下面一起来看下TCP和UDP的报文图 从图中我们可以看出TCP和UDP中都有校验和,但是在UDP报文中,一般不使用校验和,这样可以加快数据传输的速度,但是数据的准确性可能会受到影响。

换句话说,Tcp协议都有校验和,为了保证传输数据的准确性。

3.Socket Socket包括Ip地址和端口号两部分,程序通过Socket来通信,Socket相当于操作系统的一个组件。

Socket作为进程之间通信机制,通常也称作”套接字”,用于描述IP地址和端口号,是一个通信链的句柄。

说白了,就是两个程序通信用的。

生活案例对比: Socket之间的通信可以类比生活中打电话的案例。

任何用户在通话之前,首先要占有一部电话机,相当于申请一个Socket,同时要知道对方的号码,相当于对方有一个固定的Socket,然后向对方拨号呼叫,相当于发出连接请求。

假如对方在场并空闲,拿起 电话话筒,双方就可以进行通话了。

双方的通话过程,是一方向电话机发出信号和对方从电话机接收信号的过程,相当于向socket发送数据和从socket接收数据。

通话结束后,一方挂起电话机,相当于关闭socket,撤销连接。

注意:Socket不仅可以在两台电脑之间通信,还可以在同一台电脑上的两个程序间通信。

4,端口进阶(深入) 通过IP地址确定了网络中的一台电脑后,该电脑上可能提供很多提供服务的应用,每一个应用都对应一个端口。

在Internet上有很多这样的主机,这些主机一般运行了多个服务软件 ,同时提供几种服务,每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务(应用程序) 例如:http 使用80端口, ftp使用21端口 smtp使用25端口5.Socket分类 Socket主要有两种类型:流式Socket 是一种面向连接的Socket,针对于面向连接的TCP服务应用,安全,但是效率低 2,数据报式Socket 是一种无连接的Socket,对应于无连接的UDP服务应用,不安全,但效率高6. Socket一般应用模式(服务器端和客户端) 服务器端的Socket(至少需要两个) 01.一个负责接收客户端连接请求(但不负责与客户端通信) 02.每成功接收到客户端的连接便在服务器端产生一个对应的复杂通信的Socket 021.在接收到客户端连接时创建 022. 为每个连接成功的客户端请求在服务器端都创建一个对应的Socket(负责和客户端通信) 客户端的Socket必须指定要连接的服务器地址和端口通过创建一个Socket对象来初始化一个到服务器端的TCP连接 通过上图,我们可以看出,首先服务器会创建一个负责监听的socket,然后客户端通过socket连接到服务器指定端口,最后服务器端负责监听的socket,监听到客户端有连接过来了,就创建一个负责和客户端通信的socket。

下面我们来看下Socket更具体的通信过程:Socket的通讯过程 服务器端: 01,申请一个socket 02,绑定到一个IP地址和一个端口上 03,开启侦听,等待接收连接 客户端: 01,申请一个socket 02,连接服务器(指明IP地址和端口号) 服务器端接收到连接请求后,产生一个新的socket(端口大于1024)与客户端建立连接并进行通信,原监听socket继续监听。

注意:负责通信的Socket不能无限创建,创建的数量和操作系统有关。

7.Socket的构造函数 Public Socket(AddressFamily addressFamily,SocketType socketType,ProtocolType protocolTYpe) AddressFamily:指定Socket用来解析地址的寻址方案。

例如:InterNetWork指示当Socket使用一个IP版本4地址连接 SocketType:定义要打开的Socket的类型 Socket类使用ProtocolType枚举向Windows Sockets API通知所请求的协议注意: 1,端口号必须在 1 和 65535之间,最好在1024以后。

2,要连接的远程主机必须正在监听指定端口,也就是说你无法随意连接远程主机。

如:IPAddress addr = IPAddress.Parse("127.0.0.1");IPEndPoint endp = new IPEndPoint(addr,,9000); 服务端先绑定:serverWelcomeSocket.Bind(endp) 客户端再连接:clientSocket.Connect(endp) 3,一个Socket一次只能连接一台主机 4,Socket关闭后无法再次使用 5,每个Socket对象只能与一台远程主机连接。

如果你想连接到多台远程主机,你必须创建多个Socket对象。

8.Socket常用类和方法 相关类: IPAddress:包含了一个IP地址 IPEndPoint:包含了一对IP地址和端口号方法: Socket():创建一个Socket Bind():绑定一个本地的IP和端口号(IPEndPoint) Listen():让Socket侦听传入的连接吃那个病,并指定侦听队列容量 Connect():初始化与另一个Socket的连接 Accept():接收连接并返回一个新的Socket Send():输出数据到Socket Receive():从Socket中读取数据 Close():关闭Socket,销毁连接 接下来,我们同一个简单的服务器和客户端通信的案例,来看下Sokcet的具体用法,效果图如下:关键代码:服务器端代码: 1 private void Form1_Load(object sender, EventArgs e) 2 5 Control.CheckForIllegalCrossThreadCalls = false; 11 private void btnListen_Click(object sender, EventArgs e) 13 { 15 //ip地址 17 IPAddress ip = IPAddress.Parse(txtIP.Text); 19 // IPAddress ip = IPAddress.Any; 21 //端口号 23 IPEndPoint point=new IPEndPoint(ip,int.Parse(txtPort.Text)); 25 //创建监听用的Socket 27 /* 29 * AddressFamily.InterNetWork:使用 IP4地址。

31 SocketType.Stream:支持可靠、双向、基于连接的字节流,而不重复数据。

此类型的 Socket 与单个对方主机进行通信,并且在通信开始之前需要远程主机连接。

Stream 使用传输控制协议 (Tcp) ProtocolType 和 InterNetworkAddressFamily。

33 ProtocolType.Tcp:使用传输控制协议。

35 */ 37 //使用IPv4地址,流式socket方式,tcp协议传递数据 39 Socket socket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); 41 //创建好socket后,必须告诉socket绑定的IP地址和端口号。

43 //让socket监听point 45 try 47 { 49 //socket监听哪个端口 51 socket.Bind(point); 53 //同一个时间点过来10个客户端,排队 55 socket.Listen(10); 57 ShowMsg("服务器开始监听"); 59 Thread thread = new Thread(AcceptInfo); 61 thread.IsBackground = true; 63 thread.Start(socket); 65 } 67 catch (Exception ex) 69 { 73 ShowMsg(ex.Message); 75 } 77 } 79 //记录通信用的Socket 81 Dictionary dic=new Dictionary(); 83 // private Socket client; 85 void AcceptInfo(object o) 87 { 89 Socket socket = o as Socket; 91 while (true) 93 { 95 //通信用socket 97 try 99 {101 //创建通信用的Socket103 Socket tSocket = socket.Accept();105 string point = tSocket.RemoteEndPoint.ToString();107 //IPEndPoint endPoint = (IPEndPoint)client.RemoteEndPoint;109 //string me = Dns.GetHostName();//得到本机名称111 //MessageBox.Show(me);113 ShowMsg(point + "连接成功!");115 cboIpPort.Items.Add(point);117 dic.Add(point, tSocket);119 //接收消息121 Thread th = new Thread(ReceiveMsg);123 th.IsBackground = true;125 th.Start(tSocket);127 }129 catch (Exception ex)131 {133 ShowMsg(ex.Message);135 break;137 }139 }141 }143 //接收消息145 void ReceiveMsg(object o)147 {149 Socket client = o as Socket;151 while (true)153 {155 //接收客户端发送过来的数据157 try159 {161 //定义byte数组存放从客户端接收过来的数据163 byte[] buffer = new byte[1024 * 1024];165 //将接收过来的数据放到buffer中,并返回实际接受数据的长度167 int n = client.Receive(buffer);169 //将字节转换成字符串171 string words = Encoding.UTF8.GetString(buffer, 0, n);175 ShowMsg(client.RemoteEndPoint.ToString() + ":" + words);177 }179 catch (Exception ex)181 {183 ShowMsg(ex.Message);185 break;187 }189 }191 }195 void ShowMsg(string msg)197 {199 txtLog.AppendText(msg+"\r\n");201 }205 private void Form1_FormClosing(object sender, FormClosingEventArgs e)207 {209 //主窗体关闭时关闭子线程213 }215 //给客户端发送消息217 private void btnSend_Click(object sender, EventArgs e)219 {221 try223 {225 ShowMsg(txtMsg.Text);227 string ip = cboIpPort.Text;229 byte[] buffer = Encoding.UTF8.GetBytes(txtMsg.Text);231 dic[ip].Send(buffer);233 // client.Send(buffer);235 }237 catch (Exception ex)239 {241 ShowMsg(ex.Message);243 }247 }客户端代码: 1 Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 2 3 private void btnConnection_Click(object sender, EventArgs e) 7 //连接到的目标IP 9 IPAddress ip = IPAddress.Parse(txtIP.Text); 11 //IPAddress ip = IPAddress.Any; 13 //连接到目标IP的哪个应用(端口号!) 15 IPEndPoint point=new IPEndPoint(ip,int.Parse(txtPort.Text)); 17 try 19 { 21 //连接到服务器 23 client.Connect(point); 25 ShowMsg("连接成功"); 27 ShowMsg("服务器" + client.RemoteEndPoint.ToString()); 29 ShowMsg("客户端:" + client.LocalEndPoint.ToString()); 31 //连接成功后,就可以接收服务器发送的信息了 33 Thread th=new Thread(ReceiveMsg); 35 th.IsBackground = true; 37 th.Start(); 39 } 41 catch (Exception ex) 43 { 45 ShowMsg(ex.Message); 47 } 49 } 51 //接收服务器的消息 53 void ReceiveMsg() 55 { 57 while (true) 59 { 61 try 63 { 65 byte[] buffer = new byte[1024 * 1024]; 67 int n = client.Receive(buffer); 69 string s = Encoding.UTF8.GetString(buffer, 0, n); 71 ShowMsg(client.RemoteEndPoint.ToString() + ":" + s); 73 } 75 catch (Exception ex) 77 { 79 ShowMsg(ex.Message); 81 break; 83 } 85 } 89 } 93 void ShowMsg(string msg) 95 { 97 txtInfo.AppendText(msg+"\r\n"); 99 }103 private void btnSend_Click(object sender, EventArgs e)105 {107 //客户端给服务器发消息109 if (client!=null)111 {113 try115 {117 ShowMsg(txtMsg.Text);119 byte[] buffer = Encoding.UTF8.GetBytes(txtMsg.Text);121 client.Send(buffer);123 }125 catch (Exception ex)127 {129 ShowMsg(ex.Message);131 }133 }137 }141 private void ClientForm_Load(object sender, EventArgs e)143 {145 Control.CheckForIllegalCrossThreadCalls = false;147 } 好了,到这里我们对Socket的讨论就告一个段落了。

开,发之,Socket,网络编程,TCP,层次,模型,、,端

加入收藏
               

Asp.net建立网络磁盘映射代码实现

点击下载文档

格式为doc格式

  • 账号登录
社交账号登录