Sprawdzanie obecności serwera zdalnego .NET - czy moje podejście jest prawidłowe?

Nie można ustawić limitu czasu połączenia w wywołaniu zdalnym .NET. Dokumentacja czasami odnosi się doTcpChannel właściwości, które rzekomo to robią, aledyskusje i najnowszydocs Odkryłem, że nie jest to możliwe. Można ustawić limit czasu dla samego połączenia zdalnego, ale nie dla początkowej próby połączenia. Utknąłeś z domyślnym 45-sekundowym limitem czasu.

Z różnych powodów nie mogę używać WCF.

Powoduje to problem, gdy serwer zdalny zniknie. Jeśli spróbuję nawiązać połączenie zdalne, utknę na tych 45 sekund. To nie jest dobrze. Chcę sprawdzić obecność serwera zdalnego. Pingowanie go za pomocąPingTimeout jest najprostszym podejściem, ale chcę sprawdzić konkretnie serwer zdalny, a nie tylko maszynę.

Po kilku eksperymentach opracowałem takie podejście:

Asynchronicznie rozpocznij połączenie gniazda TCP z portem zdalnym.Poczekaj na zakończenie połączenia lub upłynie limit czasu (za pomocą zdarzenia ManualResetEvent).Jeśli wywołanie asynchroniczne połączenia powiodło się, zwróć sukces. W przeciwnym razie zwróć błąd.

To działa, ale nie jestem pewien, czy korzystam z mojegoWaitHandle i gniazdo. Chciałbym również zapewnić równoległe kontrole WRT z zabezpieczeniem wątków, które, jak sądzę, zrobiłem. Mój kod jest poniżej. Czy widzisz jakieś problemy z moim podejściem?

private static bool IsChannelOpen(string ip, int port, int timeout)
{
    IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse(ip), port);
    Socket client = new Socket(endpoint.AddressFamily,
              SocketType.Stream, ProtocolType.Tcp);
    SocketTestData data = new SocketTestData()
              { Socket = client, ConnectDone = new ManualResetEvent(false) };
    IAsyncResult ar = client.BeginConnect
              (endpoint, new AsyncCallback(TestConnectionCallback), data);

    // wait for connection success as signaled from callback, or timeout 
    data.ConnectDone.WaitOne(timeout);
    client.Close();
    return data.Connected;
}

private static void TestConnectionCallback(IAsyncResult ar)
{
    SocketTestData data = (SocketTestData)ar.AsyncState;
    data.Connected = data.Socket.Connected;
    if (data.Socket.Connected)
    {
        data.Socket.EndConnect(ar);
    }
    data.ConnectDone.Set(); // signal completion
}

public class SocketTestData
{
    public Socket Socket { get; set; }
    public ManualResetEvent ConnectDone { get; set; }
    public bool Connected { get; set; }
}

questionAnswers(2)

yourAnswerToTheQuestion