- 浏览: 102029 次
- 性别:
- 来自: 大连
文章分类
最新评论
最近要实现访问远程主机的共享目录中的一个文件。遇到了权限问题。google了一下,找到了几种解决方法,记录如下:
一、调用Net use命令
// 使用方法:
//if (Connect("192.168.1.48", "用户名", "密码"))
//{
// File.Copy(@"\\192.168.1.48\共享目录\test.txt", @"e:\\test.txt", true);
//}
public bool Connect(string remoteHost, string userName, string passWord)
{
bool Flag = true;
Process proc = new Process();
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.CreateNoWindow = true;
try
{
proc.Start();
string command = @"net use \\" + remoteHost + " " + passWord + " " + " /user:" + userName + ">NUL";
proc.StandardInput.WriteLine(command);
command = "exit";
proc.StandardInput.WriteLine(command);
while (proc.HasExited == false)
{
proc.WaitForExit(1000);
}
string errormsg = proc.StandardError.ReadToEnd();
if (errormsg != "")
Flag = false;
proc.StandardError.Close();
}
catch (Exception ex)
{
Flag = false;
}
finally
{
proc.Close();
proc.Dispose();
}
return Flag;
}
二、调用WNetAddConnection2、WNetAddConnection3或者NetUseAdd函数,进行磁盘映射。
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace WindowsApplication1
{
public class MyMap
{
[DllImport("mpr.dll", EntryPoint = "WNetAddConnection2")]
public static extern uint WNetAddConnection2(
[In] NETRESOURCE lpNetResource,
string lpPassword,
string lpUsername,
uint dwFlags);
[DllImport("Mpr.dll")]
public static extern uint WNetCancelConnection2(
string lpName,
uint dwFlags,
bool fForce);
[StructLayout(LayoutKind.Sequential)]
public class NETRESOURCE
{
public int dwScope;
public int dwType;
public int dwDisplayType;
public int dwUsage;
public string LocalName;
public string RemoteName;
public string Comment;
public string Provider;
}
// remoteNetworkPath format: @"\\192.168.1.48\sharefolder"
// localDriveName format: @"E:"
public static bool CreateMap(string userName, string password, string remoteNetworkPath, string localDriveName)
{
NETRESOURCE myNetResource = new NETRESOURCE();
myNetResource.dwScope = 2; //2:RESOURCE_GLOBALNET
myNetResource.dwType = 1; //1:RESOURCETYPE_ANY
myNetResource.dwDisplayType = 3; //3:RESOURCEDISPLAYTYPE_GENERIC
myNetResource.dwUsage = 1; //1: RESOURCEUSAGE_CONNECTABLE
myNetResource.LocalName = localDriveName;
myNetResource.RemoteName = remoteNetworkPath;
myNetResource.Provider = null;
uint nret = WNetAddConnection2(myNetResource, password, userName, 0);
if (nret == 0)
return true;
else
return false;
}
// localDriveName format: @"E:"
public static bool DeleteMap(string localDriveName)
{
uint nret = WNetCancelConnection2(localDriveName, 1, true);
if (nret == 0)
return true;
else
return false;
}
public void test()
{
// 注意:
// remote、local、username的格式一定要正确,否则可能出现错误
string remote = @"\\192.168.1.48\generals";
string local = @"P:";
string username = @"Domain\UserName";
string password = @"Password";
bool ret = MyMap.CreateMap(username, password, remote, local);
if (ret)
{
//do what you want:
// ...
//File.Copy("q:\\test.htm", "c:\\test.htm");
MyMap.DeleteMap(local);
}
}
}
}
三、使用WebClient类
由于WebClient类可以上传下载文件,并且支持以http:、https:和file:开头的URI,所以可以用WebClient类来传输文件。
添加System.Net命名空间后使用如下代码下载文件:
private void Test1()
{
try
{
WebClient client = new WebClient();
NetworkCredential cred = new NetworkCredential("username", "password", "172.16.0.222");
client.Credentials = cred;
client.DownloadFile("file://172.16.0.222/test/111.txt", "111.txt");
}
catch (Exception ex)
{
// 如果网络很慢,而文件又很大,这时可能有超时异常(Time out)。
}
}
public void Test2()
{
try
{
WebClient client = new WebClient();
NetworkCredential cred = new NetworkCredential("username", "password", "domain");
client.Credentials = cred;
client.DownloadFile("file://172.16.0.222/test/111.txt", "111.txt");
}
catch (Exception ex)
{
// 如果网络很慢,而文件又很大,这时可能有超时异常(Time out)。
}
}
类似的还可以试试WebRequest、FileWebRequest等:
WebRequest req = WebRequest.Create("file://138.12.12.14/generals/test.htm");
NetworkCredential cred = new NetworkCredential("username", "password", "IP");
req.Credentials = cred;
WebResponse response = req.GetResponse();
Stream strm = response.GetResponseStream();
StreamReader r = new StreamReader(strm);
... ...
四、角色模拟
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.IO;
namespace Test
{
public class Test
{
// logon types
const int LOGON32_LOGON_INTERACTIVE = 2;
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
// logon providers
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_PROVIDER_WINNT50 = 3;
const int LOGON32_PROVIDER_WINNT40 = 2;
const int LOGON32_PROVIDER_WINNT35 = 1;
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int LogonUser(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);
private WindowsImpersonationContext impersonationContext;
public bool impersonateValidUser(String userName, String domain, String password)
{
WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if (RevertToSelf())
{
// 这里使用LOGON32_LOGON_NEW_CREDENTIALS来访问远程资源。
// 如果要(通过模拟用户获得权限)实现服务器程序,访问本地授权数据库可
// 以用LOGON32_LOGON_INTERACTIVE
if (LogonUser(userName, domain, password, LOGON32_LOGON_NEW_CREDENTIALS,
LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
if (impersonationContext != null)
{
System.AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
IPrincipal pr = System.Threading.Thread.CurrentPrincipal;
IIdentity id = pr.Identity;
CloseHandle(token);
CloseHandle(tokenDuplicate);
return true;
}
}
}
}
if (token != IntPtr.Zero)
CloseHandle(token);
if (tokenDuplicate != IntPtr.Zero)
CloseHandle(tokenDuplicate);
return false;
}
public void undoImpersonation()
{
impersonationContext.Undo();
}
public void TestFunc()
{
bool isImpersonated = false;
try
{
if (impersonateValidUser("UserName", "Domain", "Password"))
{
isImpersonated = true;
//do what you want now, as the special user
// ...
File.Copy(@"\\192.168.1.48\generals\now.htm", "c:\\now.htm", true);
}
}
finally
{
if (isImpersonated)
undoImpersonation();
}
}
}
}
五、比较
方法一通过调用Shell命令Net Use实现,有点笨拙。
方法二和方法一有些相似之处。映射远程资源,然后访问。
方法三由于会有超时异常出现,所以在网络速度快、传输小文件时是可以的。
方法四通过身份模拟实现远程资源访问。一些服务器进程就是通过这种方式运行的。这种方法也是我的最爱。
六、要注意的地方
关于这几种方法,google后都可以找到一些文章。但是等到自己实际测试时,有时会出现各种小错误,
这些错误基本来源于两方面:
1、函数的参数选择有问题,和自己的环境不相符。
比如
public static extern int LogonUser(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
中的dwLogonType,要访问远程资源就要用LOGON32_LOGON_NEW_CREDENTIALS,
要模拟本机用户就要用LOGON32_LOGON_INTERACTIVE。
2、函数的参数格式有问题。
a、比如
public static extern int LogonUser(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
中的lpszUserName、lpszDomain、lpszPassword就要写清楚。
我就在这遇到过问题,第一次测试时,远程服务器就是一台独立的文件服务器,这是我的调用方式:
LogonUser("myname", "192.168.1.48", "password", LOGON32_LOGON_NEW_CREDENTIALS,
LOGON32_PROVIDER_DEFAULT, ref token);
第二次测试时,远程服务器是域MyDomain中的一个成员服务器,提供文件服务。这时代码就应该是:
LogonUser("myname", "MyDomain", "password", LOGON32_LOGON_NEW_CREDENTIALS,
LOGON32_PROVIDER_DEFAULT, ref token);
注意,代码中是MyDomain而不是IP地址。
b、再如:
参考上面代码
string remote = @"\\192.168.1.48\generals";
string local = @"P:";
string username = @"Domain\UserName";
string password = @"Password";
如果@"\\192.168.1.48\generals"变成@"\\192.168.1.48\generals\”就会出错;
如果是域中的用户,那么把@"Domain\UserName"变成@"UserName"就会出错。
一、调用Net use命令
// 使用方法:
//if (Connect("192.168.1.48", "用户名", "密码"))
//{
// File.Copy(@"\\192.168.1.48\共享目录\test.txt", @"e:\\test.txt", true);
//}
public bool Connect(string remoteHost, string userName, string passWord)
{
bool Flag = true;
Process proc = new Process();
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.CreateNoWindow = true;
try
{
proc.Start();
string command = @"net use \\" + remoteHost + " " + passWord + " " + " /user:" + userName + ">NUL";
proc.StandardInput.WriteLine(command);
command = "exit";
proc.StandardInput.WriteLine(command);
while (proc.HasExited == false)
{
proc.WaitForExit(1000);
}
string errormsg = proc.StandardError.ReadToEnd();
if (errormsg != "")
Flag = false;
proc.StandardError.Close();
}
catch (Exception ex)
{
Flag = false;
}
finally
{
proc.Close();
proc.Dispose();
}
return Flag;
}
二、调用WNetAddConnection2、WNetAddConnection3或者NetUseAdd函数,进行磁盘映射。
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace WindowsApplication1
{
public class MyMap
{
[DllImport("mpr.dll", EntryPoint = "WNetAddConnection2")]
public static extern uint WNetAddConnection2(
[In] NETRESOURCE lpNetResource,
string lpPassword,
string lpUsername,
uint dwFlags);
[DllImport("Mpr.dll")]
public static extern uint WNetCancelConnection2(
string lpName,
uint dwFlags,
bool fForce);
[StructLayout(LayoutKind.Sequential)]
public class NETRESOURCE
{
public int dwScope;
public int dwType;
public int dwDisplayType;
public int dwUsage;
public string LocalName;
public string RemoteName;
public string Comment;
public string Provider;
}
// remoteNetworkPath format: @"\\192.168.1.48\sharefolder"
// localDriveName format: @"E:"
public static bool CreateMap(string userName, string password, string remoteNetworkPath, string localDriveName)
{
NETRESOURCE myNetResource = new NETRESOURCE();
myNetResource.dwScope = 2; //2:RESOURCE_GLOBALNET
myNetResource.dwType = 1; //1:RESOURCETYPE_ANY
myNetResource.dwDisplayType = 3; //3:RESOURCEDISPLAYTYPE_GENERIC
myNetResource.dwUsage = 1; //1: RESOURCEUSAGE_CONNECTABLE
myNetResource.LocalName = localDriveName;
myNetResource.RemoteName = remoteNetworkPath;
myNetResource.Provider = null;
uint nret = WNetAddConnection2(myNetResource, password, userName, 0);
if (nret == 0)
return true;
else
return false;
}
// localDriveName format: @"E:"
public static bool DeleteMap(string localDriveName)
{
uint nret = WNetCancelConnection2(localDriveName, 1, true);
if (nret == 0)
return true;
else
return false;
}
public void test()
{
// 注意:
// remote、local、username的格式一定要正确,否则可能出现错误
string remote = @"\\192.168.1.48\generals";
string local = @"P:";
string username = @"Domain\UserName";
string password = @"Password";
bool ret = MyMap.CreateMap(username, password, remote, local);
if (ret)
{
//do what you want:
// ...
//File.Copy("q:\\test.htm", "c:\\test.htm");
MyMap.DeleteMap(local);
}
}
}
}
三、使用WebClient类
由于WebClient类可以上传下载文件,并且支持以http:、https:和file:开头的URI,所以可以用WebClient类来传输文件。
添加System.Net命名空间后使用如下代码下载文件:
private void Test1()
{
try
{
WebClient client = new WebClient();
NetworkCredential cred = new NetworkCredential("username", "password", "172.16.0.222");
client.Credentials = cred;
client.DownloadFile("file://172.16.0.222/test/111.txt", "111.txt");
}
catch (Exception ex)
{
// 如果网络很慢,而文件又很大,这时可能有超时异常(Time out)。
}
}
public void Test2()
{
try
{
WebClient client = new WebClient();
NetworkCredential cred = new NetworkCredential("username", "password", "domain");
client.Credentials = cred;
client.DownloadFile("file://172.16.0.222/test/111.txt", "111.txt");
}
catch (Exception ex)
{
// 如果网络很慢,而文件又很大,这时可能有超时异常(Time out)。
}
}
类似的还可以试试WebRequest、FileWebRequest等:
WebRequest req = WebRequest.Create("file://138.12.12.14/generals/test.htm");
NetworkCredential cred = new NetworkCredential("username", "password", "IP");
req.Credentials = cred;
WebResponse response = req.GetResponse();
Stream strm = response.GetResponseStream();
StreamReader r = new StreamReader(strm);
... ...
四、角色模拟
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.IO;
namespace Test
{
public class Test
{
// logon types
const int LOGON32_LOGON_INTERACTIVE = 2;
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
// logon providers
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_PROVIDER_WINNT50 = 3;
const int LOGON32_PROVIDER_WINNT40 = 2;
const int LOGON32_PROVIDER_WINNT35 = 1;
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int LogonUser(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);
private WindowsImpersonationContext impersonationContext;
public bool impersonateValidUser(String userName, String domain, String password)
{
WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if (RevertToSelf())
{
// 这里使用LOGON32_LOGON_NEW_CREDENTIALS来访问远程资源。
// 如果要(通过模拟用户获得权限)实现服务器程序,访问本地授权数据库可
// 以用LOGON32_LOGON_INTERACTIVE
if (LogonUser(userName, domain, password, LOGON32_LOGON_NEW_CREDENTIALS,
LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
if (impersonationContext != null)
{
System.AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
IPrincipal pr = System.Threading.Thread.CurrentPrincipal;
IIdentity id = pr.Identity;
CloseHandle(token);
CloseHandle(tokenDuplicate);
return true;
}
}
}
}
if (token != IntPtr.Zero)
CloseHandle(token);
if (tokenDuplicate != IntPtr.Zero)
CloseHandle(tokenDuplicate);
return false;
}
public void undoImpersonation()
{
impersonationContext.Undo();
}
public void TestFunc()
{
bool isImpersonated = false;
try
{
if (impersonateValidUser("UserName", "Domain", "Password"))
{
isImpersonated = true;
//do what you want now, as the special user
// ...
File.Copy(@"\\192.168.1.48\generals\now.htm", "c:\\now.htm", true);
}
}
finally
{
if (isImpersonated)
undoImpersonation();
}
}
}
}
五、比较
方法一通过调用Shell命令Net Use实现,有点笨拙。
方法二和方法一有些相似之处。映射远程资源,然后访问。
方法三由于会有超时异常出现,所以在网络速度快、传输小文件时是可以的。
方法四通过身份模拟实现远程资源访问。一些服务器进程就是通过这种方式运行的。这种方法也是我的最爱。
六、要注意的地方
关于这几种方法,google后都可以找到一些文章。但是等到自己实际测试时,有时会出现各种小错误,
这些错误基本来源于两方面:
1、函数的参数选择有问题,和自己的环境不相符。
比如
public static extern int LogonUser(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
中的dwLogonType,要访问远程资源就要用LOGON32_LOGON_NEW_CREDENTIALS,
要模拟本机用户就要用LOGON32_LOGON_INTERACTIVE。
2、函数的参数格式有问题。
a、比如
public static extern int LogonUser(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
中的lpszUserName、lpszDomain、lpszPassword就要写清楚。
我就在这遇到过问题,第一次测试时,远程服务器就是一台独立的文件服务器,这是我的调用方式:
LogonUser("myname", "192.168.1.48", "password", LOGON32_LOGON_NEW_CREDENTIALS,
LOGON32_PROVIDER_DEFAULT, ref token);
第二次测试时,远程服务器是域MyDomain中的一个成员服务器,提供文件服务。这时代码就应该是:
LogonUser("myname", "MyDomain", "password", LOGON32_LOGON_NEW_CREDENTIALS,
LOGON32_PROVIDER_DEFAULT, ref token);
注意,代码中是MyDomain而不是IP地址。
b、再如:
参考上面代码
string remote = @"\\192.168.1.48\generals";
string local = @"P:";
string username = @"Domain\UserName";
string password = @"Password";
如果@"\\192.168.1.48\generals"变成@"\\192.168.1.48\generals\”就会出错;
如果是域中的用户,那么把@"Domain\UserName"变成@"UserName"就会出错。
相关推荐
在C#编程中,访问远程主机的权限问题...总的来说,C#访问远程主机的权限问题涉及到网络编程、身份验证、权限配置等多个方面。通过正确使用API函数或命令行工具,并结合适当的错误处理和调试,可以有效地解决这类问题。
在C#编程中,访问远程...总结来说,C#访问远程主机资源的方式主要包括调用系统命令和使用Windows API。在实际应用中,根据项目需求和环境限制,选择合适的方法,并注意处理可能出现的权限问题,确保安全性和稳定性。
文件查看功能意味着软件能列出并访问远程主机的文件系统。这需要实现文件和目录的枚举、读取、写入及删除等操作。在C#中,可以使用Directory和File类来完成这些任务,同时考虑到权限和安全性,可能需要使用到Windows...
8. **性能优化**:为了提高远程服务的响应速度和系统资源利用率,开发者可能对通信协议、数据结构、缓存策略等方面进行了优化。例如,使用高效的序列化方法、减少不必要的网络通信,或者利用缓存来减少重复计算。 ...
本资源提供了一个C#实现的远程连接功能的完整代码示例,它超越了操作系统默认提供的远程连接功能,提供了更强大的控制和交互能力。 远程连接通常涉及到网络通信和系统管理,C#通过.NET Framework或.NET Core提供了...
C#远程桌面连接工具是一种基于Microsoft的C#编程语言实现的应用程序,用于远程控制和管理其他计算机。在本文中,我们将深入探讨C#实现远程桌面连接的原理、关键技术和源码解析。 首先,理解远程桌面连接的基础是...
### VC调用WMI访问远程主机查询结果错误的问题解决方法 #### 一、问题背景与概述 在使用Visual C++(VC)通过Windows Management Instrumentation (WMI)接口访问远程计算机资源时,可能会遇到返回结果始终为零的...
这个程序是用Visual Studio 2008(VS2008)开发环境构建的,对于那些刚刚接触C#和.NET Framework的人来说,它是一个很好的学习资源。 系统信息探测程序通常会涉及到以下几个核心知识点: 1. **基础C#语法**:C#...
具体的操作方法如下,可能比较笨拙,但最终还是解决了问题,供大家参考使用: 首先,开始/运行,在运行中输入指令mstsc(这是自带的远程访问(图型界面)命令),点击确定; 然后,在弹出的对话框中输入连接的远程...
【描述】提到的"Window下查看远程桌面源码"是指在Windows环境下,通过读取和理解源代码,来实现对远程计算机桌面的访问。这通常需要对TCP/IP协议、网络通信以及Windows API有深入的理解。TCP(传输控制协议)是网络...
虚拟主机管理系统是一款基于C#编程语言开发的应用程序,主要用于管理和维护服务器上的虚拟主机服务。C#是一种现代化的、类型安全的面向对象编程语言,由微软公司推出,广泛应用于Windows平台和.NET框架,它提供了...
同时,确保应用程序有足够的权限访问远程桌面服务。 7. **优化用户体验**:根据需要,还可以实现其他功能,如屏幕自动适应、声音同步、文件传输等,以提高用户体验。 综上所述,这个"C#远程桌面连接源码"提供了...
在网络编程中,常见的一个问题是当 Server 或 Client 中的一方主动断开连接时,另一方可能会遇到 “远程主机强迫关闭了一个现有连接” 的异常。这会导致程序异常终止,无法继续执行后续逻辑。 **问题叙述** 当一方...
此外,`UdpClient`类还包含了一些属性,如`Active`,它表示是否已建立与远程主机的连接,以及`Client`,它提供了对基础网络套接字的访问。 在实际应用中,使用`UdpClient`发送UDP数据包通常有两种情况: 1. 已知...
这种方法可以显著减少对目标机器的资源占用,提高可维护性和灵活性。接下来,我们将详细介绍如何在VS_2010环境下利用C#实现这一功能。 #### 流程控制 在实现远程调试的过程中,需要确保能够从“客户计算机”(即...
2. **网络编程**:在C#中,要访问远程计算机的资源,你需要理解网络通信的基本概念。这通常涉及到 `System.Net` 命名空间,其中包含 `System.Net.NetworkInformation` 和 `System.Net.Sockets` 类,它们用于获取网络...
分别介绍了C#语言基础、Windows窗体及常用控件、Windows高级控件、控件公共属性、方法及事件、数据库开发、文件、数据流与注册表、GDI+绘图技术和C#高级编程,共包含562个C#编程中常用的属性、方法、类和各种技术,...
Send用于将数据缓冲区中的数据发送到连接的远程主机,而Receive则用于接收来自远程主机的数据。 5. **异步编程**:为了提高程序的响应性和可扩展性,C#提供了异步版本的SendAsync和ReceiveAsync方法,它们允许程序...