2

C# で Windows フォーム アプリケーションを使用しています。サーバーに非同期で接続しているソケット クライアントを使用しています。何らかの理由で接続が切断された場合、ソケットがサーバーにすぐに再接続しようとするようにします。私の受信ルーチンは次のようになります

        public void StartReceiving()
    {
        StateObject state = new StateObject();
        state.workSocket = this.socketClient;
        socketClient.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(OnDataReceived), state);
    }

    private void OnDataReceived(IAsyncResult ar)
    {
        try
        {
            StateObject state = (StateObject)ar.AsyncState;
            Socket client = state.workSocket;

            // Read data from the remote device.
            int iReadBytes = client.EndReceive(ar);
            if (iReadBytes > 0)
            {
                byte[] bytesReceived = new byte[iReadBytes];
                Buffer.BlockCopy(state.buffer, 0, bytesReceived, 0, iReadBytes);
                this.responseList.Enqueue(bytesReceived);
                StartReceiving();
                receiveDone.Set();
            }
            else
            {
                NotifyClientStatusSubscribers(false);
            }
        }
        catch (Exception e)
        {

        }
    }

NotifyClientStatusSubscribers(false) が呼び出されると、関数 StopClient が実行されます。

public void StopClient()
    {
        this.canRun = false;
        this.socketClient.Shutdown(SocketShutdown.Both);
        socketClient.BeginDisconnect(true, new AsyncCallback(DisconnectCallback), this.socketClient);
    }

    private void DisconnectCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the socket from the state object.
            Socket client = (Socket)ar.AsyncState;

            // Complete the disconnection.
            client.EndDisconnect(ar);

            this.socketClient.Close();
            this.socketClient = null;
        }
        catch (Exception e)
        {

        }
    }

ここで、次の関数を呼び出して再接続を試みます。

    public void StartClient()
    {
        this.canRun = true;
        this.MessageProcessingThread = new Thread(this.MessageProcessingThreadStart);
        this.MessageProcessingThread.Start();
        this.socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        this.socketClient.LingerState.Enabled = false;
    }

    public void StartConnecting()
    {
        socketClient.BeginConnect(this.remoteEP, new AsyncCallback(ConnectCallback), this.socketClient);
    }

    private void ConnectCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the socket from the state object.
            Socket client = (Socket)ar.AsyncState;

            // Complete the connection.
            client.EndConnect(ar);

            // Signal that the connection has been made.
            connectDone.Set();

            StartReceiving();

            NotifyClientStatusSubscribers(true);
        }
        catch(Exception e)
        {
            StartConnecting();
        }
    }

接続が利用可能になるとソケットは再接続しますが、数秒後に次の未処理の例外が発生します:「接続要求は、既に接続されているソケットで行われました。」

これはどのように可能ですか?

4

1 に答える 1

2

ConnectCallbackで例外が発生し、実際に正常に接続されている場合は可能です。の catch ステートメントにブレーク ポイントを設定し、ConnectCallbackそこで発生する例外があるかどうかを確認します。現在、例外が発生したことを通知するものは何もありません。

于 2012-03-28T17:04:05.547 に答える