通过TCP / IP发送XML

时间:2012-10-22 14:17:18

标签: c# xml stream

我有一个通过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;
}

1 个答案:

答案 0 :(得分:3)

这是问题所在:

while (PGConnectionStream.DataAvailable);

这只是检查现在是否有任何可用的数据 。它无法判断以后是否会有更多内容进入。

目前尚不清楚是否需要在同一个流中容纳多条消息。如果不这样做,那就非常简单:只需继续阅读,直到Read返回非正值。否则,您需要考虑一个指示数据结束的方案:

  • 分隔符(在转发消息中的分隔符方面很难)
  • 长度前缀(意味着在知道将获得多少数据之前无法开始写作)
  • Chunked(长度前缀,但在单个块的基础上,用(例如)一个0长度的块来表示数据的结束)

(根据Adriano的评论,当您真正想要同步执行所有操作时使用异步API是没有意义的......并且您的变量命名不一致。)