[C#] Socket.Connect() i Timeout

0

Witam.
Piszę program który ma za zadanie, łączyc się z kilkoma/kilkunastoma zewnętrznymi serwerami.
Jednak problem się zaczyna kiedy któryś z nich jest offline, bo socket rzuca wyjątek po ~30sekundach, co jest stanowczo za duzym czasem ;/

Na msdn znalazlem opcje dla socketow SendTimeout, i ReceiveTimeout ale one dotyczą wyłącznie funkcji Send() i Receive(), a nie Connect ;/

Czy znacie jakis sposob na ustawienie tego ?

Pozdrawiam i Proszę o pomoc :)

0

Szukanie na google to pierwsze co zrobiłem ... i okazuje sie ze całkiem sporo osób ma ten sam problem.
Z racji ze nie znalazlem nigdzie gotowego rozwiązania które by mnie zaspokoilo, wiec postaralem sie stworzyc wlasne.

Ogólna koncepcja wyglada tak:
-zaczynam sie laczyc asynchroniczna metoda BeginConnect
-tworze obiekt timer i ustawiam mu czas na powiedzmy 1sek
*jesli socket polaczy sie zatrzymuje timer
*jesli nie timer zamyka socketa i pokazuje odpowiedni komunikat

A oto kod ktory w ten sposób powstal (ma za zadanie wyłącznie laczyc sie)

    class ConnectSocket
    {
        private static Socket socket;
        private static System.Timers.Timer aTimer;

        static void Test(IAsyncResult ar)
        {
            aTimer.Stop();
            Console.WriteLine("polaczylem!");
        }

        private static void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            Console.WriteLine("zamykam polaczenie");
            socket.Close();
        }

        public ConnectSocket(string host, int port)
        {
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                IPHostEntry ipHostInfo = Dns.Resolve(host);
                IPAddress ipAddress = ipHostInfo.AddressList[0];
                IPEndPoint lep = new IPEndPoint(ipAddress, port);
                socket.BeginConnect(lep, new AsyncCallback(ConnectSocket.Test), socket);
                aTimer = new System.Timers.Timer(1000);
                aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
                aTimer.AutoReset = false;
                aTimer.Enabled = true;
            }
            catch (SocketException s)
            {
                Console.WriteLine(s.Message);
            }
        }
    }

Jednak "cos" jest nie tak. Czasem pokazuje sie komunikat Ze zamknieto polaczenie, a potem ze sie polaczyl ...

0

IMO jedna sekunda to może być troche mało....

0

Jeśli socket się połączy a timer tyknie w bardzo małym odstępie czasu (powiedzmy jednocześnie) to lecą obie procedury jedna po drugiej (już się nawzajem nie mogą zatrzymać). Spróbuj tak (nie testowałem):

        static void Test(IAsyncResult ar)
        {
            lock(this)
            {
               aTimer.Stop();
               if(socket.Connected) Console.WriteLine("polaczylem!");
            }
        }

        private static void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            lock(this)
            {
               if(!socket.Connected) 
               {
                  Console.WriteLine("zamykam polaczenie");
                  socket.Close();
               }
            }
        }

1 użytkowników online, w tym zalogowanych: 0, gości: 1