3

多くのソケットとの間でデータを送受信するソフトウェアに取り組んでいます。これは高度に非同期であり、そのため次のシナリオが心配です: N スレッドが同じソケットにデータを送信しようとしています。これは、同時に BeginSend を呼び出す N 個のスレッドです。

明確化: 私はスレッドを使用していませんが、「システム」が使用しています。ドキュメントには次のように書かれています。「アプリケーションが BeginSend を呼び出すと、システムは別のスレッドを使用して指定されたコールバック メソッドを実行します

SocketExceptionで失敗するかどうかを知るために、このテストを行いました(それに関するドキュメントが見つからないため):

    [Test]
    public void DoIt2()
    {
        var byteCount = 0;
        var manualEvents = new[] { new ManualResetEvent(false), new ManualResetEvent(false), new ManualResetEvent(false) };
        var message = new byte[] { 0x01, 0x02, 0x03, 0x04 };
        var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        var callback = new AsyncCallback(ar =>{
            var resetEvent = (ManualResetEvent)ar.AsyncState;
            Interlocked.Add(ref byteCount,  socket.EndSend(ar));
            resetEvent.Set();
        });

        socket.Connect("127.0.0.1", 8000);
        socket.BeginSend(message, 0, message.Length, SocketFlags.None, callback, manualEvents[0]);
        socket.BeginSend(message, 0, message.Length, SocketFlags.None, callback, manualEvents[1]);
        socket.BeginSend(message, 0, message.Length, SocketFlags.None, callback, manualEvents[2]);

        WaitHandle.WaitAll(manualEvents);

        socket.Close();
        Assert.AreEqual(12, byteCount);
    }

緑を通過しました。ただし、何か問題があるかどうかを知る必要があります。EndSend/EndReceive が呼び出される前に、BeginSend/BeginReceive を複数回呼び出すことができると仮定しても安全ですか? つまり、次のパターンは大丈夫ですか?

  1. 送信開始
  2. 送信開始
  3. 送信開始
  4. 送信終了
  5. 送信終了
  6. 送信終了

到着データの順番は?これが TCP であることはわかっていますが、BeginSend が非同期であることを考えると、1 から送信されたデータは 2 と 3 より前に到着するのでしょうか?

ありがとうございました。

4

1 に答える 1