Ping.SendAsync()从0.0.0.0返回重播,如何获得ping地址
本文关键字:何获得 地址 ping 返回 SendAsync Ping | 更新日期: 2023-09-27 18:01:28
我在c#中的Ping.SendAsync()函数有问题。我ping了一些ip地址,但其中一些是错误的。我需要从列表中删除错误的地址。但是,由于p_PingCompleted 事件args.replay。地址为0.0.0.0?下面是我的代码:
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.
您可以使用UserState
属性和锁来确保对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);
}
}
}
}
在异步调用中,发送Ping对象(或游戏对象,你正在处理的任何列表)作为对象状态,然后从Ping completed事件中,如果地址无效,只需从列表中删除该对象。
我认为这与你如何使用SendAsync(string, object)
有关。
在MSDN,它有一个很好的例子。使用SendAsync(String, Int32, Byte[], PingOptions, Object)
或SendAsync(IPAddress, Int32, Byte[], PingOptions, Object)
代替。遵循这个例子,它应该为你工作。