PDA

View Full Version : سوال: ديسكانت شدن بي دليل يك ارتباط tcp



joker
سه شنبه 25 مرداد 1390, 20:00 عصر
ك ماژول ClientSocket1 توي دلفي دارم كه مستقيم به يك پورت در LocalHost متصل هست
هر اطلاعاتي كه بهش بدم مستقيم Write ميكنه روي اون پورت و هر اطلاعاتي از اون پورت بهش برسه ميفرسته به يك ماژول ديگه و اون ميفرسته به يه جاي ديگه بيرون از كامپيوتر با اين قسمت مشكلي ندارم...
در حالت عادي كه تعداد پكتهاي ارسالي و دريافتي در واحد ثانيه زياد نيست مشكلي ندارم و برنامه به خوبي كار ميكنه
ولي وقتي سرعت نقل و انتقال ميره بالا 20 پكت در ثانيه ( 10 تا ارسال 10 تا دريافت ) يهو از سمت localhost كانكشن ارتباطي با ClientSocket1 ديسكانكت ميشه!
كسي تاحالا به همچين مشكلي برخورد كرده ؟

پيوست : حجم پكت ها به طور معمول كمتر از 10 بايت هست. و حداكثر 160 بايت
پيوست 2: نرم افزاري كه روي localhost هست مشكلي نداره و در حالت معمولي با ارتباطات اورجينال خودش درست كار ميكنه ساعتها......
پيوست 3: تمام پكتهاي ارسالي و دريافتي چك شدند ( دونه به دونه )‌چيزي غير از استراكچر استاندارد قاطيشون نبوده كه بگم اشكال از اينه.
پيوست 4: سرعت cpu نهايتا 2-3 درصدش گرفته ميشه و هميشه آزاده. رم هم همينطور آزاده و جائي به حد پر شدن نميرسند در اين پروسه

چيزي به ذهنتون ميرسه ؟

vcldeveloper
چهارشنبه 26 مرداد 1390, 01:47 صبح
چرا از Indy به جای ClientSocket قدیمی و پر Bug استفاده نمی کنید؟

joker
چهارشنبه 26 مرداد 1390, 15:10 عصر
شايد خنده دار باشه ولي توي ماژول Tcp Lient INDY متدي كه تشخيص بده ديتارسيده (‌همان OnRead ) را پيدا نكردم ، مثالي هم براش نديدم تقريبا همه بعد از ارسال به سرور منتظر پاسخ مونده بودند كه اين مورد در كار من سازگار نيست و هر لحظه ممكنه ديتايي برسه خلاصه نفهميدم كه بقيه چكار كردند ، شما اگه برات زحمت نيست ميتوني اين موضوع را بهم با يك مثال راهنمائي كني؟

پيوست :
من يكسري توضيحات براي دوستان ديگه اينجا (http://www.iranled.com/forum/thread-21560.html) دادم خودClientSocket را به صورت دستي زير بار گذاشتم قات نزد كه نزد ، احتمالي كه دادم عدم ترتيب جوابهاي رسيده يا پكت لاست شدن ديتاها روي پروتكل udp هست ( زير تست دستي با سرعت زياد در هر 500 پكت ، حدود 2 الي 10 پكت به صورت رندوم از دست ميداد)
( سرور يه سوالي ميپرسه ، جواب صحيح بهش نميرسه يا بعد از يك جواب ديگه مياد بهش ميرسه ) و سرور ميگه چون جواب اشتباهه ، ريجكت. ( سرور من يك بازي تقريبا قديمي هست بنام واركرافت3 )

joker
جمعه 28 مرداد 1390, 11:27 صبح
توي اين مدت كه داشتم روش كار ميكردم ديدم بعله نه اشكال سوكت هست نه خطاي برنامه نويسي ، سرور اين بازي هر 100 ميلي ثانيه يك پكت اعتبارسنجي به كلاينت ميفرسته و كلاينت يك جواب هش شده برميگردونه ، هر وقت يكي از اين دوتا در مسير گم بشه ترتيب ارسال و دريافت اين پكت اعتبارسنجي بهم ميريزه و سرورش فكر ميكنه يوزر ديسكانكت شده

براي اينكه بفهمم يك پكت UDP درست ارسال شده ( به مقصد رسيده )، سبكترين راه حل و الگوريتم كاري كه به ذهنتون مياد چيه ؟
يه چيزي شبيه به SEQ/ACK/PSH در پروتكل Tcp

vcldeveloper
یک شنبه 30 مرداد 1390, 03:22 صبح
شايد خنده دار باشه ولي توي ماژول Tcp Lient INDY متدي كه تشخيص بده ديتارسيده (‌همان OnRead ) را پيدا نكردم ، مثالي هم براش نديدم تقريبا همه بعد از ارسال به سرور منتظر پاسخ مونده بودند كه اين مورد در كار من سازگار نيست و هر لحظه ممكنه ديتايي برسه خلاصه نفهميدم كه بقيه چكار كردند ، شما اگه برات زحمت نيست ميتوني اين موضوع را بهم با يك مثال راهنمائي كني؟
Indy روش کارش با اون چیزی که در WinSock رایج هست، فرق میکنه، هر چند خودش در ساختار داخلی خودش از WinSock استفاده میکنه، اما رابطی که در اختیار برنامه نویس قرار میده به صورت Blocking کار میکنه، یعنی فراخوانی های مختلف به صورت Asynchronous نیستند. مثلا برنامه نویس از کلاینت یه درخواست به سرور ارسال میکنه، تا زمانی که پاسخ از سرور نرسیده، Thread ایی که درخواست از داخل آن ارسال شده، بلوکه میشه. این روش در اکثر مواقع باعث میشه که پیچیدگی های برنامه نویسی Socket تا حد زیادی کاهش پیدا کنه. اما در بعضی سناریوهای خاص، مثل سناریوی شما، دردسر استفاده از این شیوه بیشتر از منافع اش هست. الان شما اگر بخواید همین کار رو با indy پیاده سازی کنید، یا باید در یک Thread جداگانه یک IdUdpClient داشته باشید که مرتبا بافر ورودی را چک میکنه، یا اینکه یک idUtpServer برای دریافت پیام ها، و یک idUdpClient برای ارسال پیام داشته باشید.

در این مورد خاص؛ بهتره آخرین نسخه ICS را از سایتش دانلود کنید، و ازش استفاده کنید. ICS هم مثل Indy رایگان و اوپن سورس هست، اما مثل WinSock به صورت Asynchronous عمل میکنه، و event هایی برای خبر دادن رسیدن داده داره.


براي اينكه بفهمم يك پكت UDP درست ارسال شده ( به مقصد رسيده )، سبكترين راه حل و الگوريتم كاري كه به ذهنتون مياد چيه ؟
نمیدونم، بهش فکر نکردم؛ تا جایی که اطلاع دارم، UDP خودش هیچگونه مکانیزم کنترلی برای بررسی صحت ارسال یک پکت نداره، پس اگر قرار باشه ارسال و دریافت صحیح پکت بررسی بشه، باید دو سر اتصال خودشان در این زمینه به یک توافق برسند، چیزی مثل پروتکل TFTP (http://en.wikipedia.org/wiki/Trivial_File_Transfer_Protocol)که بر روی UDP هست. ولی در شرایط شما که سرور تحت کنترل شما نیست، من نمیدونم چه کاری می تونید انجام بدید، که این تضمین حاصل بشه.

joker
یک شنبه 30 مرداد 1390, 12:04 عصر
ممنون
اشکال از سیستم سوکتها نبود ، کلا مجبور شدم صورت مسئله را پاک کنم

پیوست: یه سیستم دیدم به اسم ِUDT (http://www.codeproject.com/KB/IP/udt.aspx)
کارش جالب بود ، انتقال دیتا با حجم و سرعت زیاد بر روی پروتکل udp با تضمین رسیدن صحیح اطلاعات