Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# socket Networking
I'm writing some code in C# for the first time which requires talking to a network attached device using HTTP. Unfortunately the device is broken and so I cannot use the HttpWebRequest/HttpWebResponse classes, so I'm having to do it myself with TcpClient and NetworkStream.
 
I've got the following code:
 
// make and send the request
byte[] sendBytes = Encoding.ASCII.GetBytes("GET / HTTP/1.1" + Environment.NewLine + Environment.NewLine);
netStream.Write(sendBytes, 0, sendBytes.Length);
 
// read and display the response
byte[] bytes = new byte[tcpClient.ReceiveBufferSize];
int bytesRead = netStream.Read(bytes, 0, tcpClient.ReceiveBufferSize);
Console.Writeline(bytesRead + " bytes read");
string returnData = Encoding.ASCII.GetString(bytes);
Console.Writeline(returnData);
 
Now I know for certain that my response should be 191 bytes long. However I only get 40 bytes in my bytesRead buffer.
 
The only way I can make it work is by doing this:
 
// make and send the request
byte[] sendBytes = Encoding.ASCII.GetBytes("GET / HTTP/1.1" + Environment.NewLine + Environment.NewLine);
netStream.Write(sendBytes, 0, sendBytes.Length);
 
// sleep while waiting for a complete response
Thread.Sleep(50)
 
// read and display the response
byte[] bytes = new byte[tcpClient.ReceiveBufferSize];
int bytesRead = netStream.Read(bytes, 0, tcpClient.ReceiveBufferSize);
Console.Writeline(bytesRead + " bytes read");
string returnData = Encoding.ASCII.GetString(bytes);
Console.Writeline(returnData)
 
Clearly this is ugly and is not robust to different network conditions, so I would like a way to avoid it.
 
I've tried various things like looping on netStream.DataAvailable and appending any further data but this doesn't get me any further.
 
Unless I have misinterpreted it, the following sentence from the NetworkStream documentation implies that this kind of messing around isn't necessary:
 
Read and write operations can be performed simultaneously on an instance of the NetworkStream class without the need for synchronization. As long as there is one unique thread for the write operations and one unique thread for the read operations, there will be no cross-interference between read and write threads and no synchronization is required.
 

Will anybody suggest an alternative?

Posted 25-Aug-10 5:32am
Edited 25-Aug-10 8:52am
v3
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

Thanks for your answer. I am sure that the incoming message is smaller than the buffer size. I have also tried the approach which is outlined on MSDN and it did not help me. This is what I meant by "looping on netStream.DataAvailable and appending any further data" in my question.
 
What I have found helps is rather than handle the raw incoming bytes, if I wrap the NetworkStream in a StreamReader and StreamWriter things seem to work without my Thread.Sleep().
 
My control loop cannot run as quickly in this manner though so I am not sure whether the reader/writer are actually helping me or whether they are just slowing things down enough to avoid the race condition (exactly what the Thread.Sleep() was doing).
 
In any case this seems to be robust at least.
 
My code now looks like this:
 
StreamReader reader = new StreamReader(netStream);
StreamWriter writer = new StreamWriter(netStream);
 
// make and send the request
writer.Write("GET / HTTP/1.1" + Environment.NewLine + Environment.NewLine);
writer.Flush();
 
// read and display the response
string returnData = reader.ReadToEnd();
Console.Writeline(returnData)
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

I think you probably need to keep reading until there is no more data available. The remote computer may not present the entire response in a single packet so your code should allow for that fact and also use the contents of the response to stop reading when you have the entire message. Take a look at the sample code here[^] for some more information.
  Permalink  

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 6,564
1 Sergey Alexandrovich Kryukov 6,078
2 DamithSL 5,228
3 Manas Bhardwaj 4,717
4 Maciej Los 4,150


Advertise | Privacy | Mobile
Web03 | 2.8.1411022.1 | Last Updated 25 Aug 2010
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100