之前分享過DHT磁連結種子檔案的下載下傳方法,但下載下傳種子檔案的時候失敗很多,比如傳回:Timeouts are not supported on this stream.
The remote server returned an error: (404) Not Found.
The operation has timed out.這篇文章就此分析如何解決這些BUG通路.....
繼續接着第一篇寫:使用C#實作DHT磁力搜尋的BT種子後端管理程式+資料庫設計(開源)[搜片神器]
謝謝園子朋友的支援,已經找到個VPS進行測試,國外的伺服器: h31bt.org 大家可以給提點意見...
開源位址:https://github.com/h31h31/H31DHTMgr
程式下載下傳:H31DHT下載下傳
下載下傳種子檔案的時候失敗很多,增加調試資訊總是傳回很多:Timeouts are not supported on this stream.
The operation has timed out.
附上之前的代碼:
private int DownLoadFileToSaveFile(string strURL, string fileName)
{
Int32 ticktime1 = System.Environment.TickCount;
try
{
Int32 ticktime2 = 0;
byte[] buffer = new byte[4096];
WebRequest wr = WebRequest.Create(strURL);
wr.ContentType = "application/x-bittorrent";
wr.Timeout = 300;
WebResponse response = wr.GetResponse();
int readsize = 0;
{
bool gzip = response.Headers["Content-Encoding"] == "gzip";
Stream responseStream = gzip ? new GZipStream(response.GetResponseStream(), CompressionMode.Decompress) : response.GetResponseStream();
using (MemoryStream memoryStream = new MemoryStream())
{
responseStream.ReadTimeout = 1000;
int count = 0;
do
{
count = responseStream.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, count);
readsize += count;
Thread.Sleep(1);
} while (count != 0);
ticktime2 = System.Environment.TickCount;
byte[] result = memoryStream.ToArray();
Thread.Sleep(10);
using (BinaryWriter writer = new BinaryWriter(new FileStream(fileName, FileMode.Create)))
{
writer.Write(result);
}
}
Int32 ticktime3 = System.Environment.TickCount;
//H31Debug.PrintLn("下載下傳成功" + strURL + ":" + readsize.ToString() + ":" + (ticktime2 - ticktime1).ToString() + "-" + (ticktime3 - ticktime2).ToString());
}
return 1;
}
catch (Exception e)
{
Int32 ticktime3 = System.Environment.TickCount;
//H31Debug.PrintLn("下載下傳失敗" + strURL + ":" + (ticktime3 - ticktime1).ToString());
return -2;
}
}
測試在國内伺服器上情況很少時間,一放到國外伺服器上就出現此問題,網上搜尋資料最終顯示是
參考1:http://stackoverflow.com/questions/9791423/httpwebresponse-readtimeout-timeouts-not-supported
經過代碼分析,原來Stream responseStream裡面使用的TIMEOUT參數設定.
Stream responseStream = gzip ? new GZipStream(response.GetResponseStream(), CompressionMode.Decompress) : response.GetResponseStream();
using (MemoryStream memoryStream = new MemoryStream())
{
responseStream.ReadTimeout = 1000;
int count = 0;
do
{
count = responseStream.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, count);
readsize += count;
Thread.Sleep(1);
} while (count != 0);
ticktime2 = System.Environment.TickCount;
byte[] result = memoryStream.ToArray();
Thread.Sleep(10);
using (BinaryWriter writer = new BinaryWriter(new FileStream(fileName, FileMode.Create)))
{
writer.Write(result);
}
}
然後為了防止程式界面卡住,錯誤的增加了Thread.Sleep(1);其它問題可能就出現在此地方,由于設定逾時,然後資料流就被逾時退出,進而被系統認為Stream沒有登出導緻異常,進而顯示Timeouts are not supported on this stream.
修改後的代碼為:
private int DownLoadFileToSaveFile(string strURL, string fileName,int timeout1)
{
Int32 ticktime1 = System.Environment.TickCount;
try
{
Int32 ticktime2 = 0;
byte[] buffer = new byte[4096];
WebRequest wr = WebRequest.Create(strURL);
wr.ContentType = "application/x-bittorrent";
wr.Timeout = timeout1;
WebResponse response = wr.GetResponse();
int readsize = 0;
{
bool gzip = response.Headers["Content-Encoding"] == "gzip";
Stream responseStream = gzip ? new GZipStream(response.GetResponseStream(), CompressionMode.Decompress) : response.GetResponseStream();
using (MemoryStream memoryStream = new MemoryStream())
{
int count = 0;
do
{
count = responseStream.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, count);
readsize += count;
} while (count != 0);
ticktime2 = System.Environment.TickCount;
byte[] result = memoryStream.ToArray();
Thread.Sleep(10);
using (BinaryWriter writer = new BinaryWriter(new FileStream(fileName, FileMode.Create)))
{
writer.Write(result);
}
}
Int32 ticktime3 = System.Environment.TickCount;
//H31Debug.PrintLn("下載下傳成功" + strURL + ":" + readsize.ToString() + ":" + (ticktime2 - ticktime1).ToString() + "-" + (ticktime3 - ticktime2).ToString());
}
return 1;
}
catch (WebException e)
{
Int32 ticktime3 = System.Environment.TickCount;
if (e.Status == WebExceptionStatus.Timeout)//檔案逾時
{
return -2;
}
else if (e.Status == WebExceptionStatus.ProtocolError)//檔案不存在
{
return -3;
}
else
{
H31Debug.PrintLn("下載下傳失敗" + strURL + ":" + (ticktime3 - ticktime1).ToString() + e.Status.ToString() + e.Message);
return -4;
}
}
}
測試程式後出現下載下傳失敗的HASH檔案少了很多.
The remote server returned an error: (404) Not Found. 此問題是伺服器沒有此檔案,可以采用if (e.Status == WebExceptionStatus.ProtocolError)來判斷
The operation has timed out. 此問題是時間不夠,可以增加 wr.Timeout = 300;這個時間的問題.
特此記錄一下,希望大家多指教..大家可以從開源位址:https://github.com/h31h31/H31DHTMgr下載下傳代碼一起交流下..
大家覺得好的話,希望推薦支援下...