web-dev-qa-db-ja.com

C#で動作しているインターネット接続を検出する方法

基本的に、FTPプロトコル(FtpWebRequestを使用)経由でファイルをアップロードするC#コードがあります。ただし、ファイルをアップロードする前に、まずインターネット接続が機能しているかどうかを確認したいと思います(試しても意味がない場合は、ソフトウェアはしばらくスリープしてからもう一度確認する必要があります)。 。

それを行う簡単な方法はありますか、それともファイルをアップロードして、失敗した場合はネットワーク接続がダウンしていると想定して、もう一度試すだけですか?

28
Detariael

単純な関数を使用するだけ

System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()

接続が確立されている場合は、trueまたはfalseを返します。

MSDNから:ネットワーク接続は、「アップ」とマークされており、ループバックまたはトンネルインターフェースではない場合に利用可能と見なされます。

接続がすべてではないことに注意してください。ローカルネットワークに接続でき、ルーターがインターネットに接続されていません。インターネットに接続しているかどうかを実際に確認するには、 Ping クラスを試してください。

32
Zyo

トンネルまたはループバックではないインターフェースでネットワーク接続の「アップ」状態が変化したときに発生する「ネットワーク可用性が変更されました」イベントがあります。

起動時にシステム上のすべてのネットワークアダプターの状態を読み取り、「ネットワークが利用可能」の現在の値を保存してから、このイベントをリッスンし、このイベントが発生したときにネットワーク状態変数を変更できます。これも、ダイヤルアップ接続とISDN接続を処理するように見えます。

NICがルーターに接続されており、機能している)など、考慮すべき他の要因があることは承知していますが、ルーターのインターネット接続がダウンしているか、リモートホストが応答していません。ただし、これにより、少なくともネットワーク接続がない場合(たとえば、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);
    }
}
14
Andy Shellam

私が使用できる最良の近似は、OperationalStatus型のNetworkInterface値を確認することです。

using System.Net.NetworkInformation;

public bool IsNetworkLikelyAvailable() {
  return NetworkInterface
    .GetAllNetworkInterfaces()
    .Any(x => x.OperationalStatus == OperationalStatus.Up);
}

ただし、これは概算です。このメソッドがコンピューターを返す瞬間、コンピューターのインターネット接続が失われたり、取得されたりする可能性があります。 IMOアップロードが失敗しないことを証明できないので、そのままアップロードしてエラーを処理します。

12
JaredPar

チェックが戻って「接続があります」と表示され、FTPを開始する前に接続が切断される状況を考えてみてください。

または、FTPリクエストの途中で接続が切断される場所。

とにかくこれらの状況のた​​めにコーディングする必要がありますの場合、チェックをスキップしてください

ジェイソンのコメントに応じて編集

また、反対の状態を発生させることもできます。接続を確認すると、接続は存在しませんが、しばらくすると接続が確立します。さて、あなたは何をしますか-接続が利用可能になったとしても、接続がないことについてユーザーを悩ませ始めますか?

結局のところ、大量のリソース(ネット接続、中間ルーター、ホスト、そのFTPサービス)を扱っています。これらのすべては(Sethのコメントが示すように)あなたの制御の範囲外で変更される可能性があり、事前テストで「このアップロードを完了できますか?」

OPが「バックオフして後で再試行する」アプローチを考えていることを示したので、私はそれをすべてバックグラウンドで実行し、ユーザーをまったく困らせないことが適切だと思います。 "成功しない時間。

System.Net.NetworkInformation NamespacePing Class を使用して、ファイルをアップロードする前にFTPサーバーにpingすることはできませんか?

6
Dean Kuga

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がインターネット接続を見つける方法の詳細なレジストリの説明を参照してください http://blog.superuser.com/2011/05/16/windows-7-network-awareness/

5

それを行うための非同期関数を書いただけです:

    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
        {
        }
    }
1
winsetter