webclient-webrequest please help!

K

kkb

Hello!
First, I'm sorry because of my english... I'll try to be
understandable!

I've got a strange problem using .NET 2003 C# and I haven't figured it
out for a long time. I'm implementing an application to download images
using System.NET classes (webclient, webrequest) asynchronously behind
proxy server. The reading method works like this:

System.Net.WebClient client=new System.Net.WebClient();
client.Credentials=System.Net.CredentialCache.DefaultCredentials;
while(!isEnded)
{
webRequest=(System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
webRequest.Credentials=System.Net.CredentialCache.DefaultCredentials;
webRequest.Timeout=10000;
webRequest.Proxy=System.Net.WebProxy.GetDefaultProxy();
webResponse=(System.Net.HttpWebResponse)webRequest.GetResponse();
fileSize=webResponse.ContentLength;
strResponse=client.OpenRead(url);
strLocal=new
System.IO.FileStream(filename,System.IO.FileMode.Create,System.IO.FileAccess.Write,System.IO.FileShare.None);
downBuffer=new byte[2048];
while(strLocal.Length<fileSize)
{
strResponse.BeginRead(downBuffer,0,downBuffer.Length,new
System.AsyncCallback(streamreaded),strResponse);
strLocal.Write(downBuffer,0,readed);
}
strLocal.Close();
strResponse.Close();
webResponse.Close();
}

The main loop managed to download several files.

So, the problem is the following: the read method (beginread) always
hangs in time, undeterminately. It downloads some files and then
somewhere (in the middle of a download) it stops the transfer and
hangs. I've found that if I've downloaded the file using my browser
(Firefox) before, than there will be no problem with that file -
strange... The proxy is set properly. I'm getting crazy with this. If
anyone would help me, please do it!

Thanks a lot!

Kornel
 
J

Joerg Jooss

Thus wrote kkb,
Hello!
First, I'm sorry because of my english... I'll try to be
understandable!
I've got a strange problem using .NET 2003 C# and I haven't figured it
out for a long time. I'm implementing an application to download
images using System.NET classes (webclient, webrequest) asynchronously
behind proxy server. The reading method works like this:

System.Net.WebClient client=new System.Net.WebClient();

client.Credentials=System.Net.CredentialCache.DefaultCredentials;

while(!isEnded)

{

webRequest=(System.Net.HttpWebRequest)System.Net.WebRequest.Create(url
);

webRequest.Credentials=System.Net.CredentialCache.DefaultCredentials;

webRequest.Timeout=10000;

webRequest.Proxy=System.Net.WebProxy.GetDefaultProxy();

webResponse=(System.Net.HttpWebResponse)webRequest.GetResponse();

fileSize=webResponse.ContentLength;

strResponse=client.OpenRead(url);

strLocal=new

System.IO.FileStream(filename,System.IO.FileMode.Create,System.IO.File
Access.Write,System.IO.FileShare.None);

downBuffer=new byte[2048];

while(strLocal.Length<fileSize)

{

strResponse.BeginRead(downBuffer,0,downBuffer.Length,new

System.AsyncCallback(streamreaded),strResponse);

strLocal.Write(downBuffer,0,readed);

}

strLocal.Close();

strResponse.Close();

webResponse.Close();

}

The main loop managed to download several files.

So, the problem is the following: the read method (beginread) always
hangs in time, undeterminately. It downloads some files and then
somewhere (in the middle of a download) it stops the transfer and
hangs. I've found that if I've downloaded the file using my browser
(Firefox) before, than there will be no problem with that file -
strange... The proxy is set properly. I'm getting crazy with this. If
anyone would help me, please do it!

You should have posted the AsyncCallback as well. Your async I/O code seems
rather weird to me... the while loop doesn' make sense, since after firing
off BeginRead(), you try to copy received data to the file stream without
ever waiting to actually receive any data.

Also, the assumption that you will always receive a Content-Length header
is wrong. In general, you should read from the response stream until you
receive no more input.

Cheers,
 
K

kkb

Dear Joerg Jooss!
Thanks your answer! I haven't posted my whole code, just copied out the
structure. The whole source of the download method and the
asynccallback is this:

private System.Threading.Thread thrDownload;
private System.IO.Stream strResponse;
private System.IO.Stream strLocal;
private System.Net.HttpWebRequest webRequest;
private System.Net.HttpWebResponse webResponse;
private static int PercentProgress;
private System.Boolean isEnded;
private System.Int32 readed;
private System.Threading.ManualResetEvent timermre;
private const int TTL=500;
private const int retry=5;
private const int package=2048;


private void UpdateProgress(System.Int64 BytesRead, System.Int64
TotalBytes)
{
PercentProgress=Convert.ToInt32((BytesRead*100)/TotalBytes);
progressBar1.Value=PercentProgress;
label3.Text="Downloaded "+BytesRead+" out of "+TotalBytes+"
("+PercentProgress+"%)";
}

private void Download()
{
System.String prefix="",suffix="";
System.Int32 counter=0,start=0;
System.Int64 fileSize;
if(textBox1.Text.Length<7 || (textBox1.Text.LastIndexOf('.')==-1))
{
System.Windows.Forms.MessageBox.Show(this,"Specified URL is not in
a correct format! Please check it!","Wrong
URL!",System.Windows.Forms.MessageBoxButtons.OK,System.Windows.Forms.MessageBoxIcon.Warning);
button2_Click(this, new System.EventArgs());
}
else
{
try
{
start=System.Convert.ToInt32(textBox1.Text.Substring(textBox1.Text.Length-7,3));
}
catch(System.Exception)
{
System.Windows.Forms.MessageBox.Show(this,"Specified URL is not in
a correct format! Please check it!","Wrong
URL!",System.Windows.Forms.MessageBoxButtons.OK,System.Windows.Forms.MessageBoxIcon.Warning);
button2_Click(this, new System.EventArgs());
}
counter=start;
prefix=textBox1.Text.Substring(0,textBox1.Text.Length-7);
suffix=textBox1.Text.Substring(textBox1.Text.Length-4);
}
byte[] downBuffer;
System.Timers.Timer timer1=new System.Timers.Timer();
timer1.Interval=TTL;
timer1.Elapsed+=new System.Timers.ElapsedEventHandler(timertick);
int retnum=0;
System.Net.WebClient client=new System.Net.WebClient();
client.Credentials=System.Net.CredentialCache.DefaultCredentials;
while(!isEnded)
{
try
{
webRequest=(System.Net.HttpWebRequest)System.Net.WebRequest.Create(prefix+Fill(counter.ToString())+suffix);
webRequest.Credentials=System.Net.CredentialCache.DefaultCredentials;
webRequest.Timeout=10000;
if(checkBox1.Checked)
{
webRequest.Proxy=System.Net.WebProxy.GetDefaultProxy();
webRequest.Proxy.Credentials=System.Net.CredentialCache.DefaultCredentials;
}
/*else
webRequest.Proxy=System.Net.GlobalProxySelection.GetEmptyWebProxy();*/
webResponse=(System.Net.HttpWebResponse)webRequest.GetResponse();
if(webResponse.StatusCode==System.Net.HttpStatusCode.OK &&
webResponse.ContentLength>3)
{
statusBar1.Text=System.String.Format("Downloading file:
{0}...",prefix+Fill(counter.ToString())+suffix);
fileSize=webResponse.ContentLength;
strResponse=client.OpenRead(prefix+Fill(counter.ToString())+suffix);
strLocal=new
System.IO.FileStream(Fill(counter.ToString())+suffix,System.IO.FileMode.Create,System.IO.FileAccess.Write,System.IO.FileShare.None);

downBuffer=new byte[package];
readed=1;
timermre=new System.Threading.ManualResetEvent(false);
while(readed>0)
{
readed=-1;
timermre.Reset();
strResponse.BeginRead(downBuffer,0,downBuffer.Length,new
System.AsyncCallback(streamreaded),strResponse);
timer1.Enabled=true;
timer1.Start();
timermre.WaitOne();
timer1.Stop();
timer1.Enabled=false;
if(readed<0)
++retnum;
else
{
strLocal.Write(downBuffer,0,readed);
if(strLocal.Length<=fileSize)
this.Invoke(new UpdateProgessCallback(UpdateProgress), new
object[] { strLocal.Length, fileSize });
}
}
strLocal.Close();
strResponse.Close();
}
else
button2_Click(this, new System.EventArgs());
}
catch(System.Exception ex)
{
if(System.Windows.Forms.MessageBox.Show(this,System.String.Format("{0}
files successfully downloaded.\r\n\r\nDo you want to read the
terminator
message?",((System.Int32)(counter-start)).ToString()),"Download
finished...",System.Windows.Forms.MessageBoxButtons.YesNo,System.Windows.Forms.MessageBoxIcon.Information)==System.Windows.Forms.DialogResult.Yes)
System.Windows.Forms.MessageBox.Show(this,ex.ToString(),"Thread
last recieved
message...",System.Windows.Forms.MessageBoxButtons.OK,System.Windows.Forms.MessageBoxIcon.Information);
button2_Click(this, new System.EventArgs());
}
finally
{
if(webResponse!=null)
webResponse.Close();
if(strResponse!=null)
strResponse.Close();
if(strLocal!=null)
strLocal.Close();
progressBar1.Value=0;
}
if(readed!=-1)
{
++counter;
retnum=0;
}
else if(retnum>=retry)
{
if(System.Windows.Forms.MessageBox.Show(this,"The file transfer
terminated unexpectedly. Check your
connection!","Terminated!",System.Windows.Forms.MessageBoxButtons.RetryCancel,System.Windows.Forms.MessageBoxIcon.Error)==System.Windows.Forms.DialogResult.Cancel)
{
button2_Click(this,new System.EventArgs());
return;
}
else
retnum=0;
}
}
label3.Text="Stopped...";
statusBar1.Text="Ready.";
button1.Enabled=true;
}

private void timertick(System.Object sender,
System.Timers.ElapsedEventArgs e)
{
timermre.Set();
}

private void streamreaded(System.IAsyncResult ar)
{
System.IO.Stream strm=(System.IO.Stream)ar.AsyncState;
readed=strm.EndRead(ar);
timermre.Set();
}

After beginread called, the application waits until the reading ends OR
until a time (set in variable called TTL, in milisecs) expires <-
sometimes, as I've said, the transfer stops during the beginread / read
process and I thought I should retry it if it hangs for some time. As
you see, it didn't solve the problem... :(

Kornel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top