1

BeginConnect() を使用して、TCP 接続 (TCP ソケットへの接続が成功する) をチェックする小さな c# クラスを作成しました。問題のエンドポイントが利用可能で、TCP セッションが実際に接続されている場合は、うまく機能しているように見えます。

ただし、エンドポイントがリッスンしておらず、接続がタイムアウトすると、奇妙なことが起こります。クラスは約 15 ~ 20 秒間「ハング」し続けます。これはデフォルトのタイムアウト値と一致します。

ただし、タイムアウトがトリガーされたときに socket.Close() を呼び出します。これは、MSDN ですべての非同期操作をキャンセルすると言われています。

接続が成功しない場合、クラスがアプリケーションのシャットダウンを防止するのはなぜですか? 私は何を間違っていますか?

    public class CheckTCP
{
    #region "Member Variables"

        // socket connect timeout value
        private int _timeout = 2000;

        // check complete event
        public event EventHandler<CheckCompletedEventArgs> CheckCompleted;

        // perform TCP connect check
        public void PerformCheck(EndPoint Socket)
        {
            StateObject state = new StateObject();
            state.Me = this;
            state.WorkSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            state.TimeoutTimer = new Timer();
            state.TimeoutTimer.Interval = _timeout;
            state.TimeoutTimer.Elapsed += (sender, e) => timeout_elapsed(sender, e, state);
            state.TimeoutTimer.Start();
            state.WorkSocket.SendTimeout = _timeout;
            state.WorkSocket.ReceiveTimeout = _timeout;
            state.WorkSocket.BeginConnect(Socket, new AsyncCallback(ConnectCallback), state);
        }

        // connection callback
        private static void ConnectCallback(IAsyncResult ar)
        {
            StateObject state = (StateObject) ar.AsyncState;
            state.TimeoutTimer.Stop();
            state.TimeoutTimer.Dispose();

            CheckCompletedEventArgs ea = new CheckCompletedEventArgs();

            if (state.WorkSocket.Connected)
            {
                state.WorkSocket.EndConnect(ar);
                state.WorkSocket.Close();
                ea.Success = true;
                state.Me.OnCheckCompleted(ea);
            }
            else
            {
                ea.Success = false;
                state.Me.OnCheckCompleted(ea);
            }

            state.WorkSocket.Dispose();
            state.Me = null;
        }

        // timeout callback
        private void timeout_elapsed(object sender, EventArgs e, StateObject state)
        {
            state.TimeoutTimer.Stop();
            state.WorkSocket.Close();
        }
    #endregion

        // raiseevent helper
        protected virtual void OnCheckCompleted(CheckCompletedEventArgs e)
        {
            // raise the event
            EventHandler<CheckCompletedEventArgs> handler = CheckCompleted;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        // checkcompleted event args class
        public class CheckCompletedEventArgs : EventArgs
        {
            public bool Success { set; get; }
        }

        // async state object
        public class StateObject
        {
            public EndPoint EndpointSocket { set; get; }
            public Socket WorkSocket { set; get; }
            public Timer TimeoutTimer { set; get; }
            public CheckTCP Me { set; get; }
        }

}
4

0 に答える 0