Hello everybody. I've got quite a weird problem.
I'm writing a wrapper for TcpClient to send and receive HTTP requests. The main reason I don't use the built-in WebRequest is because I need a support for SOCKS proxies, and WebRequest does not support it.
Anyway, in one of my tests(That use no proxy, just ordinary TcpClient), I've got a weird problem: requests to a certain domain(or to be precise - requiests to coder.io), require a Thread.Sleep of 200 milliseconds to get the stream ready. If I write into the stream without giving the pause, the remote server never returns anything(and than a timeout is thrown).
All other tests on other domains had no such problem ever, but I can never know for sure, as probably there are other servers that will act in a similar manner.
Question is, is there some way to know if a stream is ready to receive data?
Here are a few code snippets:
private Stream GetStream(TcpClient client)
{
Stream stream = client.GetStream();
if (this.IsSsl())
stream = Ssl.GetSslStream(stream, Uri.Host);
return stream;
}
public ExtraWebResponse GetResponse()
{
timeoutMillis = Environment.TickCount + Timeout;
GetGetParams();
var client = Proxy == null
? new TcpClient(Uri.Host, Port)
: Proxy.GetTcpClient(Uri.Host, Port);
var stream = GetStream(client);
Thread.Sleep(200); // Here's the weird part - if I don't include this line - coder.io returns no data.
try
{
var headers = GetHeaders(); //generates HTTP request headers
using (var writer = new StreamWriter(stream, ContentEncoding ?? Encoding.Default))
{
stream.WriteTimeout = timeoutMillis - Environment.TickCount;
stream.ReadTimeout = timeoutMillis - Environment.TickCount;
writer.Write(headers);
writer.Flush();
var response = new ExtraWebResponse(this);
var encoding = Encoding.Default;
bool isEOF;
response.ReadStatus(ReadLine(stream, encoding, out isEOF)); //reads the response status line
ReadHeaders(stream, response, encoding); // reads HTTP response headers
ReadContent(stream, response); //reads the response content
return response;
}
}
finally
{
stream.Close();
}
}