15

C# (.Net Framework 4.0) で古代の VB6 プログラムを書き直しています。工場フロアの産業機器と通信します。VB6 は古い COM ベースのソケット ソフトウェアを使用していました。.Net Socket クラスを使用しています。

機器にメッセージを送信すると、応答が返されることを期待しているので、応答を聞く必要があることを知っています。ただし、機器はメッセージを警告なしで非同期に送信することもできます(たとえば、障害や問題を示すため)。だから私はいつもそれらを受け取る必要があります。だから私が本当に欲しいのは、機器から何かが来るたびに呼び出されるイベントハンドラーです。

Socket クラスは、受信イベント処理に BeginReceive/EndReceive スキームを使用しているようです。プログラムの開始時に一度だけ BeginReceive を実行して、すべての受信メッセージのイベント ハンドラを定義できますか?それとも、プログラム全体で常に BeginReceive/EndReceive を実行する必要がありますか?

これを行う正しい方法を明確にしていただきありがとうございます。

4

1 に答える 1

12

あなたはサーバーですか?

あなたがサーバーの場合、ソケット接続をリッスンし、ソケット接続を受け入れて保存します。BeginReceive次に、保存されたソケットで呼び出します。このBeginReceiveメソッドでは、データを受信して​​処理するためのコールバック関数を提供します。

データを受信すると、コールバックが発生します。コールバック関数はEndReceive、保存された接続で呼び出します。これは、データを取得/処理する場所です。BeginReceiveまた、さらにデータを待つために再度呼び出します。

このように、BeginReceiveandEndReceiveは循環して実行されます。常にデータを受信し、さらにデータを待っています。

例を次に示します。

void WaitForData(SocketState state)
{
  try
  {
    state.Socket.BeginReceive(state.DataBuffer, 0, state.DataBuffer.Length, SocketFlags.None, new AsyncCallback(ReadDataCallback), state);
  }
  catch (SocketException se)
  {
    //Socket has been closed  
    //Close/dispose of socket
  }
}

public void ReadDataCallback(IAsyncResult ar)
{
  SocketState state = (SocketState)ar.AsyncState;
  try
  {
    // Read data from the client socket.
    int iRx = state.Socket.EndReceive(ar);

    //Handle Data....
    WaitForData(state);
  }
  catch (ObjectDisposedException)
  {
    //Socket has been closed  
    //Close/dispose of socket
  }
  catch (SocketException)
  {
    //Socket exception
    //Close/dispose of socket
  }
}

編集: あなたのコメントによると、ここに C# 非同期クライアントの例があります: http://msdn.microsoft.com/en-us/library/bbx2eya8.aspx

BeginReceive/はEndReceiveサーバーと同様に機能します。

于 2013-01-08T17:52:17.883 に答える