我有一个 C# 代码,它基本上通过 FTP 协议(使用FtpWebRequest
)上传文件。但是,我想在尝试上传文件之前先确定是否有可用的互联网连接(因为,如果没有尝试,软件应该只是休眠一段时间并再次检查) .
有没有一种简单的方法可以做到这一点,或者我应该尝试上传文件,万一它失败了再试一次,假设网络连接已关闭?
我有一个 C# 代码,它基本上通过 FTP 协议(使用FtpWebRequest
)上传文件。但是,我想在尝试上传文件之前先确定是否有可用的互联网连接(因为,如果没有尝试,软件应该只是休眠一段时间并再次检查) .
有没有一种简单的方法可以做到这一点,或者我应该尝试上传文件,万一它失败了再试一次,假设网络连接已关闭?
当网络连接的“启动”状态在不是隧道或环回的接口上发生更改时,会触发“网络可用性更改”事件。
您可以在启动时读取系统上所有网络适配器的状态,存储“网络可用”的当前值,然后侦听此事件并在此事件触发时更改您的网络状态变量。这看起来也将处理拨号和 ISDN 连接。
当然还有其他因素需要考虑,例如 NIC 连接到路由器(并且正在工作)但路由器上的 Internet 连接已关闭,或者远程主机没有响应,但这至少会阻止您尝试如果一开始就没有网络连接(例如 VPN 或 ISDN 链接断开),则建立一个无法正常工作的连接。
这是一个 C# 控制台应用程序 - 启动它运行,然后禁用或拔下您的网络连接 :-)
class Program
{
static bool networkIsAvailable = false;
static void Main(string[] args)
{
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface nic in nics)
{
if (
(nic.NetworkInterfaceType != NetworkInterfaceType.Loopback && nic.NetworkInterfaceType != NetworkInterfaceType.Tunnel) &&
nic.OperationalStatus == OperationalStatus.Up)
{
networkIsAvailable = true;
}
}
Console.Write("Network availability: ");
Console.WriteLine(networkIsAvailable);
NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
Console.ReadLine();
}
static void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
{
networkIsAvailable = e.IsAvailable;
Console.Write("Network availability: ");
Console.WriteLine(networkIsAvailable);
}
}
我认为您可以使用的最佳近似值OperationalStatus
是检查类型的值NetworkInterface
。
using System.Net.NetworkInformation;
public bool IsNetworkLikelyAvailable() {
return NetworkInterface
.GetAllNetworkInterfaces()
.Any(x => x.OperationalStatus == OperationalStatus.Up);
}
请记住,尽管这是一个近似值。当此方法返回时,计算机可能会丢失或获得 Internet 连接。IMO 我会直接上传并处理错误,因为您无法证明它不会发生。
想想你的支票回来说“连接在那里”的情况,在你可以启动你的 FTP 之前,连接断开了。
或者连接在您的 FTP 请求中途中断的地方。
鉴于无论如何您都必须为这些情况编写代码,请跳过检查
编辑以回应杰森的评论
您也可以发生相反的情况 - 当您检查连接时,不存在任何连接,但片刻之后,它们的连接出现了。那么现在你该怎么办 - 你是否开始唠叨用户没有连接,即使它现在可用?
归根结底,您要处理大量资源(您的网络连接、任何中间路由器、主机、它的 FTP 服务)。所有这些都可能在您的控制范围之外发生变化(如赛斯的评论所示),并且没有多少预测试可以回答“我能否完成此上传”这个问题?
正如 OP 表示他正在考虑“退后并稍后再试”的方法,那么我认为在后台执行所有这些操作并且根本不会惹恼用户是合适的 - 除非您一直在尝试“不合理“没有成功的时间。
如果 ping 对您来说很困难,请使用 webclient。
public static bool CheckForInternetConnection()
{
try
{
using (var client = new WebClient())
using (var stream = client.OpenRead("http://www.google.com"))
{
return true;
}
}
catch
{
return false;
}
}
或任何其他网站。编辑:您可以使用http://www.msftncsi.com/这个网站。这是一个仅为互联网连接运行的站点。请参阅有关 Windows 7 如何查找 Internet 连接的详细注册表说明http://blog.superuser.com/2011/05/16/windows-7-network-awareness/
刚刚编写了异步函数来做到这一点:
private void myPingCompletedCallback(object sender, PingCompletedEventArgs e)
{
if (e.Cancelled)
return;
if (e.Error != null)
return;
if (e.Reply.Status == IPStatus.Success)
{
//ok connected to internet, do something...
}
}
private void checkInternet()
{
Ping myPing = new Ping();
myPing.PingCompleted += new PingCompletedEventHandler(myPingCompletedCallback);
try
{
myPing.SendAsync("google.com", 3000 /*3 secs timeout*/, new byte[32], new PingOptions(64, true));
}
catch
{
}
}