2

TCP / IPを介して別のアプリケーションに接続するクラスがあり、要求を(XMLの形式で)送信し、応答を(XMLの形式で)受信します。

それは機能しますが、私には次の懸念があります。

1)それは任意の理由でのみ機能しSystem.Threading.Thread.Sleep(5000)ます; これを取り出すと、部分的なデータでクラスの最後に直接ジャンプします。ストリームの最後に到達するか、タイムアウトするまで待つ必要があります。2)あまりエレガントではありません

クラス全体を以下に示します。提案は大歓迎です。

public XDocument RetrieveData()
{
    // Initialize Connection Details
    TcpClient Connection = new TcpClient();
    Connection.ReceiveTimeout = Timeout;
    MemoryStream bufferStream = new MemoryStream();

    // Compose Request
    String Request = "";
    Byte[] Data = ASCIIEncoding.ASCII.GetBytes(Request);

    // Connect to PG
    IAsyncResult ConnectionResult = Connection.BeginConnect(IPAddress, IPPort, null, null);
    while (!Connection.Connected)
    {
        System.Threading.Thread.Sleep(1000);
    }
    Connection.EndConnect(ConnectionResult);

    NetworkStream ConnectionStream = Connection.GetStream();

    // Send the request
    ConnectionStream.Write(Data, 0, Data.Length);
    ConnectionStream.Flush();

    // TODO. Tidy this up - Wait to ensure the entire message is recieved.
    System.Threading.Thread.Sleep(5000);

    // Read the response
    StringBuilder Message = new StringBuilder();
    byte[] ReadBuffer = new byte[1024];

    if (ConnectionStream.CanRead)
    {
        try
        {
            byte[] myReadBuffer = new byte[1024];
            int BytesRead = 0;

            do
            {
                BytesRead = PGConnectionStream.Read(myReadBuffer, 0, myReadBuffer.Length);
                Message.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, BytesRead));
            }
            while (PGConnectionStream.DataAvailable);
        }
        catch
        {
        }
    }

    XDocument doc = XDocument.Parse(Message.ToString());
    return doc;
}
4

1 に答える 1

3

これが問題です:

while (PGConnectionStream.DataAvailable);

これは、現在利用可能なデータがあるかどうかをチェックするだけです。後でストリームにさらに来るかどうかはわかりません。

同じストリームに複数のメッセージを収容する必要があるかどうかは明確ではありません。そうでない場合、それは本当に簡単Readです。正でない値が返されるまで読み続けてください。それ以外の場合は、データの終わりを示すためのスキームを検討する必要があります。

  • 区切り文字(メッセージ内で区切り文字をエスケープするのは難しい)
  • 長さプレフィックス(取得するデータの量がわかるまで書き込みを開始できないことを意味します)
  • チャンク(長さプレフィックス、ただし個々のチャンクベースで、(たとえば)データの終わりを示す長さ0のチャンク)

(Adrianoのコメントによると、本当にすべてを同期的に実行したいときに非同期APIを使用することは無意味です...そして、変数の命名に一貫性がありません。)

于 2012-10-22T14:23:00.823 に答える