[英]Check if IP Address and Port are responding
我目前正在為SNMP打印機監控器軟件開發自動發現功能。 我需要一個助手方法,該方法由多個線程執行,每個線程都檢查一個范圍內的ip,以確定某個ip地址處的設備是否正在響應端口9100,從而確定它實際上是打印機,然后再發送向它的SNMP請求。
我結束了下面的方法,但是我不知道這是否是正確的方法,並且按照慣例它是否在此上下文中正確使用了Close()方法(我可以看到Dispose(),Disconnect()和Shutdown()方法也可用,該使用哪一個? 此外,我需要設置最大超時值。 5秒,因此在呈現結果之前,線程不會停留太長時間。 到目前為止,我的代碼:
private bool GetTCPPrinterResponse(IPAddress _ip)
{
int port = 9100;
bool isResponsive = false;
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
s.Connect(_ip, port);
isResponsive = true;
}
catch (SocketException)
{
isResponsive = false;
}
finally
{
s.Close();
}
return isResponsive;
}
方法編輯后:
private bool GetTCPPrinterResponse(IPAddress _ip)
{
int port = 9100;
bool isResponsive = false;
using (Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
s.ReceiveTimeout = 3000;
s.SendTimeout = 3000;
try
{
s.Connect(_ip, port);
isResponsive = true;
}
catch (SocketException)
{
isResponsive = false;
}
}
return isResponsive;
}
設置超時屬性無效。
這是檢查計算機/打印機是否在某個端口上的某個IP上在線的正確方法。 您應該調用dispose方法來釋放對象正在使用的內存。 套接字類實現IDisposable,因此最好是使用using
而不用擔心調用dispose,因為using
會為您實現。
using(Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
//...
}
套接字類具有屬性ReceiveTimeout和SendTimeout。
無需為此使用多線程。 您正在捆綁線程,這些線程最終將始終等待I / O操作完成。 相反,為什么不使用異步I / O?
public async Task<Tuple<IPAddress, bool>> GetResponse(IPAddress address)
{
using (var client = new TcpClient(AddressFamily.InterNetwork))
{
var connectTask = client.ConnectAsync(address, 80);
await Task.WhenAny(connectTask, Task.Delay(5000));
if (connectTask.IsCompleted)
return Tuple.Create(address, true);
else
return Tuple.Create(address, false);
}
}
可以進一步改善-超時機制有點浪費( Task.Delay
使用計時器,不是真正必要的),但是它易於編寫,理解和使用,並且不會不必要地浪費線程。
呼叫將如下所示:
Task<Tuple<IPAddress, bool>>[] tasks =
new []
{
GetResponse(Dns.GetHostAddresses("www.google.com").First()),
GetResponse(Dns.GetHostAddresses("www.microsoft.com").First()),
GetResponse(Dns.GetHostAddresses("www.yahoo.com").First()),
GetResponse(Dns.GetHostAddresses("www.altavista.com").First()),
};
Task.WhenAll(tasks).Wait();
foreach (var t in tasks)
t.Result.Dump(); // t.Result has the IP address and status
這將等待所有設備響應(或超時)。 當然,沒有什么可以阻止您以更具交互性的方式執行此操作-您可以像返回數據一樣輕松地更新UI。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.