3

Socket.Pool()TCP プロトコルで.NET SocketSocket.Select()を使用するシングルスレッド サーバーがあり、、、Socket.Receive().

送信するには、次を使用しました:

public void SendPacket(int clientid, byte[] packet)
{
    clients[clientid].socket.Send(packet);
}

しかし、1 つのクライアントに大量のデータを送信すると (メイン スレッド全体が停止して) 非常に遅くなったため、次のように置き換えました。

public void SendPacket(int clientid, byte[] packet)
{
    using (SocketAsyncEventArgs e = new SocketAsyncEventArgs())
    {
        e.SetBuffer(packet, 0, packet.Length);
        clients[clientid].socket.SendAsync(e);
    }
}

.NET を使用する Windows では問題なく動作しますが (完璧かどうかはわかりません)、Mono を使用する Linux では、パケットが破棄されるか、並べ替えられます (わかりません)。Linux では、Socket.Send() を使用して低速バージョンに戻すことができます。サーバー全体のソース

Linux で動作するノンブロッキング SendPacket() 関数を作成するには?

4

3 に答える 3

1

私はそれがあなたのusing声明とあなたのSendAsync呼びかけに関係していると推測します. おそらくe範囲外になり、SendAsyncまだバッファを処理している間に破棄されています。しかし、これは例外をスローする可能性があります。私は本当に推測しているだけです。usingステートメントを削除して、何が起こるかを確認してください。

于 2011-01-31T08:08:50.337 に答える
0

非同期メソッドを悪用しないことで言えます。これが実際に秩序を維持することを余儀なくされていることを示す文書はどこにもありません。スレッドに分散される scheuler の iem をキューに入れ、ドキュメントごとに順序が維持されていないことを無視することで、実装の詳細に自分自身を開くことができます。

おそらく最善の方法は次のとおりです。

  • ソケットごとにキューを用意します。
  • このキューに dasta を書き込むときに、ワーカー スレッドがない場合は、ワーク アイテム (ThreadPool) を開始してスレッドを処理します。

このようにして、順序を維持する個別のキューができます。1 つのキュー / ソケットを処理するスレッドは 1 つだけです。

于 2011-01-31T07:50:09.973 に答える
0

同じ問題が発生しました。Linux と Windows は、SendAsync に対して同じように反応しません。Linux ではデータが切り捨てられることがありますが、回避策があります。まず、キューを使用する必要があります。SendAsync を使用するたびに、コールバックを確認する必要があります。e.Offset + e.BytesTransferred < e.Buffer.Length の場合は、e.SetBuffer(e.Offset + e.BytesTransferred, e.Buffer.Length - e.BytesTransferred - e.Offset); する必要があります。SendAsync を再度呼び出します。

mono-linuxがすべてのデータを送信する前に完了したと信じている理由はわかりませんが、それは奇妙ですが、彼はそうしていると確信しています。

于 2013-12-11T18:27:15.800 に答える