2011-10-30 5 views
0

私は何度か、asyncが優れているとか、同期ソケットの代わりにasyncを使うべきだと言われていたので、それを学び始めましたが、すでに難しかったです。非同期クライアントハンドルが受信しますか?

私は、コールバックの仕組みと接続を確立する方法の基本的な感触を持っています。

I am using this msdn code as reference!

私は、コードを持っていますいくつかの問題:

  • を現在そのコードは応答して終了を読んで、テキストを送信、サーバーに接続します。サーバーを切断したり、自分で終了したりするまで、データを受信できるようにするにはどうすればいいですか? ReceiveCallbackが完了した後にReceiveを実行している間にスレッドにラップする必要がある場合は、どうすればよいかわからない。

  • 私が気づいたもう一つのことは、接続するとソケットがクライアントに割り当てられますが、コード自体は常に私がメインソケットを持っている同期ソケットと比較してわかりにくいクライアントソケットを再割り当てしていることです私たちは常になど

を協議していることを私が使用している参照が何歳でわかりませんが、あなたが、私はそれが私のために簡単であると指摘されているものの例で私を助けることができれば幸いです理解する。

UPDATE:

private void SetupRecieveCallback(Socket sock) 
    { 
     new Thread(
      delegate() 
      { 
       while (isReceiving) 
       { 
        _receiveQueue.Reset(); 
        try 
        { 
         AsyncCallback recieveData = new AsyncCallback(OnRecievedData); 
         sock.BeginReceive(m_byBuff, 0, m_byBuff.Length, SocketFlags.None, recieveData, sock); 
        } 
        catch (Exception ex) 
        { 
         _logger.Error("Setup Recieve Callback failed! " + ex.Message); 
        } 
        _receiveQueue.WaitOne(); 
       } 
      } 
     ).Start(); 
     /* 
        // The original code 
     try 
     { 
      AsyncCallback recieveData = new AsyncCallback(OnRecievedData); 
      sock.BeginReceive(m_byBuff, 0, m_byBuff.Length, SocketFlags.None, recieveData, sock); 
     } 
     catch (Exception ex) 
     { 
      _logger.Error("Setup Recieve Callback failed! " + ex.Message); 
     } 
     */ 
    } 

答えて

1

だけで受信し続けるためにコールバックで再びBeginReceive()を呼び出します。サーバーが接続を切断すると、コールバックが呼び出され、EndReceive()はObjectDisposedExceptionをスローします。これで、BeginReceive()の呼び出しを止める方法がわかります。

2番目の質問はデコードが難しい(1つだけ質問する)。私はあなたがこの声明について困惑していると推測しています:

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

ここでソケットの再割り当ては行われていません。このコードは、単に元のソケットへの参照を取得します。これは便利なテクニックですが、このコールバックを複数の接続で使用することができます。 クライアントがAsyncCallbackコンストラクタに渡されるか

 client.BeginConnect(remoteEP, 
      new AsyncCallback(ConnectCallback), client); 

注:ar.AsyncState値は、このステートメントによってソケットに持っ。コールバックで取得されたクライアントとまったく同じです。任意のオブジェクトを渡すことができます。

+0

私は、BeginReceiveについて、SetupRecieveCallback(ソケットソック)のmanualeventとloopを使ってアプリケーションを終了する代わりに、そのアプリケーションを終了させるためにループを使用する必要がありました。それ以上のことを待つことはありませんか?質問を私が一番下に行ったことの例で更新します。 – Guapo

+0

Main()メソッドで何もしなければ、アプリケーションは終了時に終了します。あなたがそこで何をしたいかわからない場合、Console.ReadLine()はそれをブロックします。 –

+0

ハンスは本当に問題があるように思えましたが、実際にはシンプルに(停止して)チェックアウトするだけで、ソケットはうまくいきました。実際には、いくつかのパケットを受信するだけで同期ソケットを使用するほうがはるかに優れているように思えます。 – Guapo

関連する問題