如何从TCP流中读取解析XML并提取目标文本内容?
ReadToEnd() Limitations As someone new to XML with only basic TCP development experience, I needed to pull specific target content (marked with red boxes) from XML data sent over a TCP connection. My first attempt using ReadToEnd() to read the entire TCP stream didn't work as expected—so I switched to a line-by-line reading approach with conditional flags to track the start and end of the content I needed to capture. Here's a breakdown of my initial code and the working updated solution:
Initial Code (Non-Functional for Target Content Capture)
This code relied on ReadToEnd() to fetch the full stream, but it failed to isolate the specific marked content properly:
using System; using System.Net.Sockets; using System.Net; using System.IO; using System.Threading; using System.Text; using System.Xml; namespace RFLY_CMD { class Program { static void Main(string[] args) { Console.WriteLine("Starting..."); TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 7362); server.Start(); Console.WriteLine("Started."); while (true) { ClientWorking cw = new ClientWorking(server.AcceptTcpClient()); new Thread(new ThreadStart(cw.DoSomethingWithClient)).Start(); } } } class ClientWorking { private Stream ClientStream; private TcpClient Client; public ClientWorking(TcpClient Client) { this.Client = Client; ClientStream = Client.GetStream(); } public void DoSomethingWithClient() { StreamWriter sw = new StreamWriter(ClientStream); StreamReader sr = new StreamReader(sw.BaseStream); string data; try { while (true) { data = sr.ReadToEnd(); if (!string.IsNullOrEmpty(data) && !string.IsNullOrWhiteSpace(data)) { //Console.Clear(); Console.WriteLine(data); //Console.WriteLine("---------------"); } sr.DiscardBufferedData(); } } finally { Console.Write("Ending..."); sw.Close(); } } } }
Updated Code (Working Solution)
The core fix here is using ReadLine() to process the stream line-by-line, paired with a boolean flag (cap) to mark when we're inside the target content block (delimited by "... start" and "... end" markers). This lets us capture exactly the content between those boundaries:
using System; using System.Net.Sockets; using System.Net; using System.IO; using System.Threading; using System.Text; namespace RFLY_CMD { class Program { static void Main(string[] args) { Console.WriteLine("Starting..."); TcpListener server = new TcpListener(IPAddress.Parse("0.0.0.0"), 7362); server.Start(); Console.WriteLine("Listening..."); Console.WriteLine(); while (true) { ClientWorking cw = new ClientWorking(server.AcceptTcpClient()); new Thread(new ThreadStart(cw.DoSomethingWithClient)).Start(); } } } class ClientWorking { private Stream ClientStream; private TcpClient Client; public ClientWorking(TcpClient Client) { this.Client = Client; ClientStream = Client.GetStream(); } public void DoSomethingWithClient() { StreamWriter sw = new StreamWriter(ClientStream); StreamReader sr = new StreamReader(sw.BaseStream); string data; bool cap = false; string full_string = null; try { while (true) { data = sr.ReadLine(); if (!string.IsNullOrEmpty(data) && !string.IsNullOrWhiteSpace(data) || cap) { if(data == "... start") { cap = true; Console.WriteLine("---START FOUND!!!---"); } if (cap) { Console.WriteLine(data); full_string += data + "--:BREAK:--"; } if (data == "... end") { cap = false; Console.WriteLine("---END FOUND!!!---"); Console.WriteLine(); Console.WriteLine("-------------FULL STRING-------------"); Console.WriteLine(full_string); } } } } finally { Console.Write("Ending..."); sw.Close(); } } } }
Key Improvements:
- Line-by-line processing:
ReadLine()handles the stream incrementally, avoiding the issue whereReadToEnd()waits for the entire stream to terminate (which often doesn't happen in persistent TCP connections). - Boundary tracking: The
capflag toggles on at the start marker and off at the end marker, ensuring we only capture content within the target block. - Content aggregation: The
full_stringvariable collects all lines in the target block, making it easy to access the complete marked content once the end marker is detected.
内容的提问来源于stack exchange,提问作者Carter Bailey

