2011-07-06 38 views
4

我在C#中的Ping.SendAsync()函数有问题。 我ping一些ip地址,但他们有些是错误的。我需要从列表中删除错误的地址。但如何,因为p_PingCompleted 事件args.replay.adress0.0.0.0? 这里是我的代码:Ping.SendAsync()从0.0.0.0返回重播,如何获取ping地址?

System.Collections.Generic.List<Game> GameList = new System.Collections.Generic.List<Game>(); 
System.Timers.Timer timer = new System.Timers.Timer(5000); 

     public StartServer() 
     { 
      this.tcpListener = new TcpListener(IPAddress.Any, 8888); 
      this.listenThread = new Thread(new ThreadStart(ListenForClients)); 
      this.listenThread.Start(); 
      Console.WriteLine("Master server running..."); 
      timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed); 
      timer.Start(); 
     } 

     void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
     { 
      Game[] games = GameList.ToArray(); 
      foreach (Game curgame in games) 
      { 
       System.Net.NetworkInformation.Ping p = new System.Net.NetworkInformation.Ping(); 
       p.PingCompleted += new System.Net.NetworkInformation.PingCompletedEventHandler(p_PingCompleted); 
       p.SendAsync(IPAddress.Parse(curgame.IP), new object()); 
      } 
      SendMessageToAll(output); 
      Console.WriteLine("Timer.Elapsed with data [" + output + "]"); 
     } 

     void p_PingCompleted(object sender, System.Net.NetworkInformation.PingCompletedEventArgs e) 
     { 
      Console.WriteLine("Ping reply from: " + e.Reply.Address.ToString() + " has " + e.Reply.RoundtripTime.ToString() + " ms."); 
      if (e.Reply.RoundtripTime == 0 || 
       e.Reply.RoundtripTime >= 2500) 
      { 
       Console.WriteLine(" Removing this server because ping is 0 or is greater than 2500 ms"); 
      } 
     } 

和输出是:

Pinging 16.5.4.3... 
Ping reply from: 0.0.0.0 has 0 ms. 
+0

什么'e.Reply.Status'? – user7116

回答

2

您可以使用UserState property和锁,以确保串行访问GameList

byte[] buffer = Encoding.ASCII.GetBytes (new string('a', 32)); 
var options = new PingOptions (32, true); 

Ping p = new Ping(); 
p.PingCompleted += p_PingCompleted; 
foreach (Game curgame in GameList.ToArray()) 
{ 
    // e.UserState will be curgame 
    p.SendAsync(IPAddress.Parse(curgame.IP), 2500, buffer, options, curgame); 
} 

然后在您的p_PingCompleted处理程序:

void p_PingCompleted(object sender, PingCompletedEventArgs e) 
{ 
    var game = (Game)e.UserState; 
    if (e.Reply.Status != IPStatus.Success) 
    { 
     Console.WriteLine(
      " Could not reach {0} ({1}), removing this server...", 
      game.IP, 
      e.Reply.Status); 
     lock (GameList) 
     { 
      GameList.Remove(game); 
     } 
    } 
    else 
    { 
     Console.WriteLine(
      "Ping reply from: {0} in {1} ms", 
      e.Reply.Address, 
      e.Reply.RoundtripTime); 
     if (e.Reply.RoundtripTime == 0 || 
      e.Reply.RoundtripTime >= 2500) 
     { 
      Console.WriteLine(" Ping too high, removing this server..."); 
      lock (GameList) 
      { 
       GameList.Remove(game); 
      } 
     } 
    } 
} 
+0

这是好的,但它并不能解释为什么他越来越为0.0.0.0的IP。 – 2011-07-06 21:14:15

+0

@ 0A0D:我会在这些情况下赌注'PingReply.Status'有点像目的地不可达。 – user7116

+0

@sixlettervariables:你也许是对 – 2011-07-06 21:19:35

1

在异步调用,送平安对象(或游戏对象,无论列表你处理)作为对象状态,然后从ping完成的事件中,只要地址无效就从列表中删除该对象。

+0

你的意思是'p.SendAsync(IPAddress.Parse(curgame.IP),curgame);'? –

+0

是的。而在刚刚坪使用完毕的代码,'GamesList.Remove(e.UserState);' –

+0

它的工作原理,谢谢! –

0

我认为它必须做你如何使用SendAsync(string, object)

MSDN,它有一个很好的例子。改为使用SendAsync(String, Int32, Byte[], PingOptions, Object)SendAsync(IPAddress, Int32, Byte[], PingOptions, Object)。遵循这个例子,它应该为你工作。