2012-03-16 8 views
1

特定のポート上のアクティブなサーバーを検索する小さなuserControlライブラリを作成しています[LAN]
私はから自分のコンピュータのするIPアドレスを取得するので、最初の[.NET 4.0] TCPソケット(IPV4に)
を使用しています:その後、私はもしそうたIPAddressの最初の3部の入力たIPAddressを取る配列<T>に重複した値があるかどうかをチェックする方法?

string sHostName = Dns.GetHostName(); 
IPHostEntry ipE = Dns.GetHostByName(sHostName); 
IPAddress[] IpA = ipE.AddressList; 

= "192.168.1.X" "192.168.1"を返します。 使用:その後、

string scanIP = IpA[i].ToString().Substring(0, IpA[i].ToString().LastIndexOf(".")) + "."; 

iはから検索: -

何が必要なのである scanIPがあるかどうかをチェックする(例:192.168.1 192.168.1に。。)複数のIPアドレスを返すことがあります。IpAは、多くのIPアドレス(無線ネットワーク、有線ネットワーク、Bluetoothネットワークなど)を返す可能性があります。 ex:my wireless ip:192.168.1.25 my ethernらIPです:192.168.1.5

は、ここに私のコードです:

public ServerDiscovery() 
    { 
     InitializeComponent(); 
     timer.Elapsed += timer_tick; 
    } 

    System.Timers.Timer timer = new System.Timers.Timer(5000); 
    List<SocketAsyncEventArgs> list = new List<SocketAsyncEventArgs>(); 

    private void btnRefresh_Click(object sender, EventArgs e) 
    { 
     listServer.Items.Clear(); 
     timer.Start(); 
     //getting array of IP Addresses. 
     IPAddress[] IpA = Dns.GetHostByName(Dns.GetHostName()).AddressList; 

     for(int j = 0; j < IpA.Length; j++) 
     { 
      if (IpA[j].AddressFamily == AddressFamily.InterNetwork) //checking if IP is version 4 
      { 
       string scanIP = IpA[j].ToString().Substring(0, IpA[j].ToString().LastIndexOf(".")) + "."; 
       if (some condition)// i need a condition to ensure that dublicated scanIP doesn't scan again 
       { 
        Parallel.For(1, 255, (i, loopState) => 
         { 
          Scan(scanIP + i); 
         }); 
       } 
      } 
     } 
    } 

    private void Scan(string ipAdd) 
    { 
     Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
     SocketAsyncEventArgs e = new SocketAsyncEventArgs(); 
     e.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(ipAdd), 9990); 
     e.UserToken = s; 
     e.Completed += new EventHandler<SocketAsyncEventArgs>(e_Completed); 
     list.Add(e); 
     s.ConnectAsync(e); 
    } 

    private void e_Completed(object sender, SocketAsyncEventArgs e) 
    { 
     if (e.ConnectSocket != null) 
     { 
      StreamReader sr = new StreamReader(new NetworkStream(e.ConnectSocket)); 
      ListViewItem item = new ListViewItem(); 
      string[] cmd = sr.ReadLine().Split('<'); 
      item.Text = cmd[0]; 
      item.SubItems.Add(((IPEndPoint)e.RemoteEndPoint).Address.ToString()); 
      item.SubItems.Add(cmd[1]); 
      AddServer(item); 
     } 
    } 

    delegate void AddItem(ListViewItem item); 
    private void AddServer(ListViewItem item) 
    { 
     if (InvokeRequired) 
     { 
      Invoke(new AddItem(AddServer), item); 
      return; 
     } 
     listServer.Items.Add(item); 
    } 

    private void timer_tick(object sender, EventArgs e) 
    { 
     timer.Stop(); 
     foreach (var s in list) 
     { 
      ((Socket)s.UserToken).Dispose(); 
     } 
    } 
+0

したがって、IPの最初の3つの部分であるユニークなscanIPの明確なリストを作成したいとしますか? –

+0

@JamesMichaelHeaちょうどいいよ。 –

+0

問題なし、他の人が私にそれを打ち負かしました:-) +1 HashSet! –

答えて

2

あなたは既に使用されているアドレスを維持するためのHashSetを採用することができます。あなたはまた、重複をチェックするためのHashSetを使用することができます

IpA = IpA.Distinct().ToArray(); 
    for(int j = 0; j < IpA.Length; j++) 
    { 
    ... 

HashSet<string> usedIP = new HashSet<string>(); 

if (!usedIp.Contains(scanIP)) 
{ 
    usedIP.Add(scanIP); 
    Parallel.For(1, 255, (i, loopState) => 
       { 
        Scan(scanIP + i); 
       }); 
} 
3

で最も単純な方法をSomeConditionを交換することはDistinct() LINQの拡張メソッドを使用することです。私はそれがより速い解決策だと思う:

HashSet<IPAddress> set = new HashSet<IPAddress>(IpA); 
    for(int j = 0; j < IpA.Length; j++) 
    { 
     if(set.Contains(IpA[j])) 
      continue; 
     set.Add(IpA[j]); 

     if (IpA[j].AddressFamily == AddressFamily.InterNetwork) //checking if IP is version 4 
     { 
      string scanIP = IpA[j].ToString().Substring(0, IpA[j].ToString().LastIndexOf(".")) + "."; 
      Parallel.For(1, 255, (i, loopState) => 
       { 
        Scan(scanIP + i); 
       }); 
     } 
    } 
+0

IpA.Distinct()にLengthプロパティがありません –

+0

正確にIpA.Distinct()を意味しましたか?Count()? –

+0

私の間違いでした。私は答えを修正した。 –

0

辞書にscanIPを追加し、まだ追加されていないことを確認してください。

Dictionary<string, string> scannedIPs = new Dictionary<string, string>(); 

... 

string scanIP = IpA[j].ToString().Substring(0, IpA[j].ToString().LastIndexOf(".")) + "."; 
if (!scannedIPs.ContainsKey(scanIP)) 
{ 
    scannedIPs.Add(scanIP, scanIP); 
+1

自己への自己の辞書?それはHashSetのためのものです:-) –

+0

ああ、はい。ハッシュセットはクライアントプロファイルでは使用できないため、代わりに辞書を決める必要があります。 –

+0

十分に公正:-) –

関連する問題