عنوان:

‫اضافه کردن قابلیت از سرگیری مجدد (resume) به HttpWebRequest


نویسنده: وحید نصیری
تاریخ: ۱۳۸۷/۱۲/۱۰ ۰۹:۵۵:۰۰
آدرس: www.dntips.ir

مطابق RFC مربوطه، اگر هدر درخواست ارسالی به سرور را کمی تغییر دهیم می‌توان بجای شروع از اولین بایت، از بایت مورد نظر شروع به دریافت فایل نمود. (البته این به شرطی است که سرور آن‌را پشتیبانی کند)

یعنی نیاز داریم که به هدر ارسالی سطر زیر را اضافه کنیم:
Range: bytes=n-
که n در اینجا حجم فایل ناقص دریافتی موجود بر حسب بایت است.
برای بدست آوردن اندازه‌ی فایل ناقص موجود می‌توان از دستور زیر استفاده کرد:
using System.IO;
long brokenLen = new FileInfo(fileNamePath).Length;

سپس اگر شیء webRequest ما به صورت زیر تعریف شده باشد:

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

فقط کافی است سطر زیر را جهت افزودن قابلیت از سرگیری مجدد دریافت فایل به این شیء افزود:

//دانلود از ادامه
webRequest.AddRange((int)brokenLen); //resume

نکته:
اگر علاقمند باشید که ریز فعالیت‌های انجام شده توسط فضای نام System.Net را ملاحظه کنید، به فایل config خود (مثلا فایل app.config برنامه)، چند سطر زیر را اضافه کنید:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.Net">
<listeners>
<add name="MyTraceFile"/>
</listeners>
</source>
</sources>

<sharedListeners>
<add
name="MyTraceFile"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="System.Net.trace.log"
/>
</sharedListeners>

<switches>
<add name="System.Net" value="Verbose" />
</switches>

</system.diagnostics>
</configuration>
به این صورت کلیه هدرهای ارسالی به سرور و ریز فعالیت‌های انجام شده در پشت صحنه‌ی کلاس‌های موجود در فایلی به نام System.Net.trace.log برای شما ثبت خواهد شد.


ملاحظات:
بدیهی است پیاده سازی قابلیت resume نیاز به موارد زیر خواهد داشت:
الف) در نظر گرفتن مسیری پیش فرض برای ذخیره سازی فایل‌ها
ب) پیدا کردن اندازه‌ی فایل موجود بر روی یک سرور و مقایسه‌ی آن با حجم فایل موجود بر روی هارد
امکان پیدا کردن اندازه‌ی یک فایل هم بدون دریافت کامل آن میسر است. خاصیت ContentLength مربوط به شیء HttpWebResponse بیانگر اندازه‌ی یک فایل بر روی سرور است و صد البته پیش از استفاده از این عدد، مقدار StatusCode شیء نامبرده را بررسی کنید. اگر مساوی OK بود، یعنی این عدد معتبر است.

نظرات

  • مهمان در ۱۳۸۷/۱۲/۱۱ ۰۰:۱۴:۰۰
    سلام استاد نصیری
    مقاله جالبی بود.یعنی این نرم افزارهای Download Manager هم از این روش استفاده میکنند؟
    یه سری از سایتها هستند که فقط یه بار میشه به این صورت ازشون دانلود کرد.یعنی اگر الان بزنیم تو Queue اون دانلود منیجر وحتی قسمتیش هم دانلود بشه اما اون دانلود رو متوقف کرده و بعد از مثلا یک اعت دوباره Resume کنیم پیغام میده که فایل پیدا نشد.آیا آدرسها تغییر میکنند؟
    آیا مثال بالا رو میشه برای گرفتن یه استریم از یک صفحه هم تعمیم داد مثلا نوشتن یک دانلودر برا youtube ؟
    ممنون از لطف شما استاد عزیز
  • وحید نصیری در ۱۳۸۷/۱۲/۱۱ ۰۲:۰۲:۰۰
    - بله. این یک استاندارد است.
    - بسته به سیاست یک سایت ممکن است فایل را پس از مدتی پاک کنند. یک سری از دانلود سنترهای عمومی به همین صورت هستند.
    - تمام فایل‌های youtube لینک مستقیم به فایل flv هم دارند. می‌شود به این صورت فایل‌های آن‌ها را دریافت کرد با قابلیت از سرگیری مجدد.
  • مهمان در ۱۳۸۷/۱۲/۱۱ ۱۶:۵۱:۰۰
    سلام
    جناب نصیری در مورد دوم باید عرض کنم که فایله پاک نمیشه و اگر دوباره بک بار صفحه رو رفرش کنیم دوباره میشه فایل رو دانلود کرد به نظر میرسه فلدرهای حاوی فایلها احتمالا تغییر نام پیدا میکنند.
    در مورد سوم که فرمودین آیا ما دسترسی مستقیم به فایل FLV رو داریم؟ کلا در اینگونه سایتها راهی برای پیدا کردنه لینکه مستقیم وجود داره؟
    ببخشید من زیاد سوال پرسیدم اما یه مسئله ای به ذهنه من رسید اینکه چطور نمیشه از RapidShare با یوزر رایگان با استفاده از نرم افزارهای مدیریت دانلود چیزی دانلود کرد؟از کجا میفهمه که الان ویندوز داره میگیره یا دانلود مینیجر؟
    ممنون از لطف شما
  • وحید نصیری در ۱۳۸۷/۱۲/۱۱ ۱۸:۴۶:۰۰
    - بله. به سورس اسکریپت زیر مراجعه کنید:
    http://userscripts.org/scripts/show/39917

    - رپیدشیر به کلاینت‌های دانلودی از اکانت پرمیوم استفاده نمی‌کنند (اکانت پرمیوم از basic authentication استفاده میکنه)، اجازه‌ی بازکردن بیشتر از یک ترد را نمی‌دهد. مرورگرها هم عموما فقط از یک ترد برای دانلود استفاده می‌کنند. اگر دانلود منیجر خودتون رو هم به یک ترد محدود کنید مثل مرورگر عمل می‌کند.