I have a class that connects to another application over TCP/IP sents a request (in the form of XML) and receives a response (also in the form of XML).
It does work however I have the following concerns:
1) It only works because of an arbitrary System.Threading.Thread.Sleep(5000); if I take this out it jumps straight to the end of the class with partial data. I need it to wait until it reaches the end of the stream or times out.
2) It is not very elegant
The entire class is listed below and any suggestions are very welcome.
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;
}
This is the problem:
That just checks whether there’s any data available right now. It can’t tell whether there’s more coming in the stream later.
It’s not clear whether you need to accommodate multiple message in the same stream. If you don’t, it’s really easy: just keep reading until
Readreturns a non-positive value. Otherwise, you’ll need to consider a scheme for indicating the end of data:(As per Adriano’s comment, using async APIs when you really want to do everything synchronously is pointless… and your variable naming is inconsistent.)