私はソケットプログラミング(私が慣れていないこと)に苦労しています.GoogleやMSDN(ひどい)から助けてくれるものは何も見つかりません。これについての謝罪非同期UDPソケットの問題
私は基本的にUDPを介して要求を受信して応答する既存のサービスを持っています。私はこれを全く変えることはできません。
また、Webapp内にそのサービスへの応答をディスパッチしてリッスンするクライアントもあります。私は与えられた既存のクライアントは、ソケットと応答スロットの配列を作成し、 "sock.Receive()"呼び出しを受信し、受け取ったデータをプッシュする無限ループメソッドを持つバックグラウンドスレッドを作成するシングルトンですスロットアレイ。これに関するすべての種類のことが私には間違っているように見え、無限のスレッドはユニットテストを中断させます。このサービスを、代わりに非同期的に送受信するように置き換えようとしています。
ポイント1:これは正しいアプローチですか?私は非ブロッキング、スケーラブル、スレッドセーフなサービスが欲しいです。
私の最初の試みは大雑把にはうまくいきましたが、取り返しのあるデータは常に予想よりも短かったです(つまり、バッファには要求されたバイト数がありませんでした)。
private Socket MyPreConfiguredSocket;
public object Query()
{
//build a request
this.MyPreConfiguredSocket.SendTo(MYREQUEST, packet.Length, SocketFlags.Multicast, this._target);
IAsyncResult h = this._sock.BeginReceiveFrom(response, 0, BUFFER_SIZE, SocketFlags.None, ref this._target, new AsyncCallback(ARecieve), this._sock);
if (!h.AsyncWaitHandle.WaitOne(TIMEOUT)) { throw new Exception("Timed out"); }
//process response data (always shortened)
}
private void ARecieve (IAsyncResult result)
{
int bytesreceived = (result as Socket).EndReceiveFrom(result, ref this._target);
}
私の2番目の試みは、私が頻繁に見たより多くのGoogleトローリングとこの再帰パターンに基づいていますが、このバージョンは常にタイムアウトします。それは決してはARecieveになる。
public object Query()
{
//build a request
this.MyPreConfiguredSocket.SendTo(MYREQUEST, packet.Length, SocketFlags.Multicast, this._target);
State s = new State(this.MyPreConfiguredSocket);
this.MyPreConfiguredSocket.BeginReceiveFrom(s.Buffer, 0, BUFFER_SIZE, SocketFlags.None, ref this._target, new AsyncCallback(ARecieve), s);
if (!s.Flag.WaitOne(10000)) { throw new Exception("Timed out"); } //always thrown
//process response data
}
private void ARecieve (IAsyncResult result)
{
//never gets here!
State s = (result as State);
int bytesreceived = s.Sock.EndReceiveFrom(result, ref this._target);
if (bytesreceived > 0)
{
s.Received += bytesreceived;
this._sock.BeginReceiveFrom(s.Buffer, s.Received, BUFFER_SIZE, SocketFlags.None, ref this._target, new AsyncCallback(ARecieve), s);
}
else
{
s.Flag.Set();
}
}
private class State
{
public State(Socket sock)
{
this._sock = sock;
this._buffer = new byte[BUFFER_SIZE];
this._buffer.Initialize();
}
public Socket Sock;
public byte[] Buffer;
public ManualResetEvent Flag = new ManualResetEvent(false);
public int Received = 0;
}
ポイント2:明らかに私はかなり間違っています。
ポイント3:私はこの権利について行くのか分かりません。リモートサービスからのデータは、どのように正しいリスニングスレッドに到達しますか?リクエストごとにソケットを作成する必要がありますか?
ここから私の快適ゾーン外です。助けが必要。
あなたはUDTライブラリを知っていますか? CSHARPで – lsalamon
または[RUDP](http://rudp.codeplex.com/)を試してください – lsalamon