PDA

View Full Version : thread ها و مسئله غیر همزمانی



ARA
سه شنبه 08 اسفند 1385, 10:24 صبح
با سلام به خدمت دوستان برنامه نویس :لبخند:
من یک برنامه نوشتم که با استفاده از سوکت tcp فایل هایی بین سرور و کلاینت رد و بدل میشه

من برای بالا بردن کارایی از multithreading باضافه asyncron socket اضافه کردم

در سرور با اونکه اگه مثلا 3 کلاینت همزمان برای یک فایل 10 mg درخواست بدن و من یک فایل رو بصورت تیکه تیکه برای همه درخواست کنندگان بفرستم مشکلی ندارم و کاملا درست کار میکنه
ولی در کلاینت دارم یک مشکلی وجود داره اونهم زمانی هست یک دو تا thread میخواهند یک فایل بزرگ رو همزمان بگیرند
اولی بدون مشکل شروع به گرفتن میکنه و زمانی که برای ترد دوم begin reccive فراخوانی میشه در حالی که اولی هنوز تموم نشده انگار تو بافر شبکه اطلاعات اونا رو هم میفته و من اطلاعات هر دو رو از دست میدم

حالا سوال : به نظر شما مشکل کجاست آیا این روش استفاده از سوکت مشکل داره یا کسی در مورد بافر شبکه و نحوه دسترسی برنامه ها به اون چیزی میدونه

ARA
سه شنبه 08 اسفند 1385, 11:55 صبح
الان یک تست دیگه انجام دادم کلا مشکل بر میگرده به multi threading چون برنامه رو فقط مولتی thread کردم باز مشکل پیش میاد


فکر کنم همون مربوط به بافر چگونه میتونم بافر رو چک کنم

mohssen_mz
چهارشنبه 09 اسفند 1385, 00:34 صبح
کسی نیست راجبه تاپیکهای بالا نظری بده ....!!!؟؟؟؟

ARA
چهارشنبه 09 اسفند 1385, 09:19 صبح
مرسی
مهم اینه که که خیلی ها لطف داشتن و اومدن دیدن
خودم نظر میدم فقط یک کم وقت میخواهم تا برنامه رو بنویسم و چک کنم

مطالب جالبی یاد گرفتتم بهتون میگم

hdv212
پنج شنبه 10 اسفند 1385, 01:07 صبح
ببینم منظورتون از چک کردن بافر چیه ؟؟ مگه خودت اطلاعاتی که از بیرون میاد رو توی متغیر نمیریزی ؟؟؟ خب میتونی اون متغیر رو خالی، یا چک کنی دیگه .. میشه سوالتو واضح تر بگی ؟؟

whitehat
پنج شنبه 10 اسفند 1385, 11:53 صبح
شما باید برای هر کلاینتی که به سرور وصل میشه یک Thread ایجاد کنید.اگر از Async استفاده می کنید و این مشکل را دارید احتمال اینکه شما برای هر کلاینت ترد مناسبی را فرخوانی نمی کنید وجود دارد .لطفا بنویسید تابع BeginRecive و BeginAccept را چگونه فراخوانی می کنید؟

ARA
شنبه 12 اسفند 1385, 10:18 صبح
سلام مرسی از لطف دوستان

من سمت سرور مشکل ندارم ثانیا من نمیتونم برای هرکانکشن یک ترد بگذارم چون احتمال اینکه کانکشن ها زیاد بشه خیلی زیاده ، من برای هر درخواست یک ترد درست میکنم و بعد از فرستادن جواب اون رو از abort میکنم در ضمن جوابهایی که سرور باید بفرسته یک فایل 10 mg میتونه باشه و ممکن است کلاینت چند فایل رو بطور همزمان بخواهد
مشکل من دقیقا به این شکل است که

کلاینت من با 2 ترد 2 درخواست همزمان به سرور میفرستد ومنتظر جواب میماند سرور بعد از رسیدن درخواسها و چک کردن صحت درخواست 2 تا فایل رو بصورت بلوک های 4096 بایتی به کلاینت میفرستد در این حالت تردهایی که در کلاینت من که منتظر جواب بودن بلوک های 4096 بایتی از سرور را گرفته و باید ذخیره کند حال مشکل اینجا رخ میده که بلوکها با هم عوض شده و هر ترد ترکیبی از بلوکها را دریافت کرده و ذخیره میکند ولی در مجموع کل باتهای دریافتی درست میباشد

راه حلی که پیدا کردم این بود که در سور یک id برای هر جواب بگذارم و همچنین باید یک ترد dispatcher در کلاینت راه اندازی کنم که جوابها را گرفته و با توجه به id به تردهای جداگانه بفرستد اینجا هم با یک مشکل دیگه برخورد کردم که نمیدونم چطوری ترد dispatcher یک بلوک رو به یک ترد بفرسته و همچنین بهش اون رو از حالت suspand در بیاره



شما باید برای هر کلاینتی که به سرور وصل میشه یک Thread ایجاد کنید.اگر از Async استفاده می کنید و این مشکل را دارید احتمال اینکه شما برای هر کلاینت ترد مناسبی را فرخوانی نمی کنید وجود دارد .لطفا بنویسید تابع BeginRecive و BeginAccept را چگونه فراخوانی می کنید؟




ببینم منظورتون از چک کردن بافر چیه ؟؟ مگه خودت اطلاعاتی که از بیرون میاد رو توی متغیر نمیریزی ؟؟؟ خب میتونی اون متغیر رو خالی، یا چک کنی دیگه .. میشه سوالتو واضح تر بگی ؟؟

whitehat
شنبه 12 اسفند 1385, 13:57 عصر
دوست عزیز اگر شما صرفا برای File Transfer می خواهید از برنامه نویسی سوکت استفاده کنید بهتره از FTP (http://www.codeproject.com/cs/internet/SimpleFTPDemo.asp) استفاده کنید.روش ساختن ID روشی هست که من گاها استفاده می کنم اما این بیشتر برای Message ها استفاده میشه نه یک فایل بزرگ ،چون شما مجبورید برای هر بسته این Id را بفرستید که سرباری به شبکه تحمیل می کنید.
با توجه به اینکه شما محدودیت در ساختن ترد دارید از Async استفاده نکنید .یک تابع Send و Recive ساده بنویسید و با آن درخواست گرفتن فایل را انجام دهید.تابع Resive تا زمانی که فایل بطور کامل گرفته نشده منتظر می ماند فقط شما باید Timeout را هندل کنید.در واقع برای این کار استفاده از Sync سوکت مناسبتر است

ARA
شنبه 12 اسفند 1385, 14:58 عصر
خوب اینجوری که تازه برمیگردیم سر خونه اول

من میخواهم همزمان چند فایل رو تو کلاینت بگیرم و چون یک پورت دارم داده های دوتا فایل با هم قاطی میشه
سرور من مشکل نداره فقط کلاینتم مشکل داره عزیزم