ورود

نسخه کامل مشاهده نسخه کامل : کار کردن با سوکت در asp.net



dogtag
02-06-2008, 10:53
ُسلام
من می خوام با سوکت وصل بشم به یه صفحه (مثلاً forum.p30wold.com:80)
و براش این رو بفرستم:

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

و هر چی میده رو بگیرم و بدم به Response.write که بریزه اش رو صفحه

همون طور که می دونید، این کد، دقیقاً همون کاریه که Browser تون وقتی که بالاش می نویسی:

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

خودکار همین ها رو انجام میده

من تا اینجای کار تونستم کانکت بشم، درخواست رو write کنم، طول جواب اومده از سرور رو هم بگیرم ولی نمی تونم بخونمش
مثل این می مونه که تو یه حلقه بی نهایت گیر کنی

این یه ور ماجراست
این هم حل بشه خودش کلی ه

---------------------------------------------------------------------------------

قضیه یه اینور هم داره:
1- چجوری کانکشن Async بسازم؟ و ازش چجوری استفاده کنم؟
2- اگر بخوام 1000 نفر هم زمان از این استفاده کنم، باید چه کنم؟


مرسی
منتظر جواب اساتیدی چون ultimator و h2 و اگر بشه، shalineh


توی PHP خیلی ماجرا راحت تر از اینجا است

دوباره مرسی

_H2_
23-06-2008, 00:59
سلام
هنوز منتظر جواب هستید و مشکلتان حل نشده؟؟؟؟؟
هم میتوانم نمونه مستقیم و البته کمی طولانی سوکت را برایتان بگذارم و هم نمونه راحت یک یا دوخطی که آدرس را بگیرد و String حاوی Html را باز گرداند...؟؟؟؟


ضمناً دوستان دیگر هم که در این تالار قبلاً سوالی پرسیده بودند، من از امروز بیشتر وقت انلاین بودم دارم، اگر مشکلشان حل نشده و هنوز ادامه دارد تاپیک را فعال کنند، اگر بلد بودم و سوادم رسید و تواستم و در حد وقت آزادم سعی میکنم جواب دهم، به هرحال میتوانند تیری در تاریکی بزنند !!!!!

dogtag
23-06-2008, 01:26
چه خوب شد که بالاخره وقت استاد آزاد شد.
(بین خودمون بمونه: ) نیما خیلی زیاد برای اینجا دل نمی سوزونه. بچه ی خوبیه ها ولی داره کار درست رو می کنه و زیاد وقت نمی ذاره
شلینه هم که مزدوج شد و رفت، شما هم که نبودی

ولی از فردا دوباره می چسبم به net. و تا توپ یاد نگیرم، ولت نمی کنم (یقه (یا یغه) ات رو بده من!)


آقا بذار اصل ماجرا رو بگم که راحت تر باشیم.

ببین، من یه سرور می شناسم که بهش وصل میشی و بهش میگی "hello, I am mr. X" و میگه که خوش تشریف آوردی عزیزم
بعد یه چیز هایی می فرسته که مثلاً میگه که "My name is Server" و بعد یه packet دیگه میفرسته و می گه که "at your service"

از اون به بعد، چیز خاصی رو نمی فرسته ولی مثلاً اگر که اتفاق خاصی بیافته مثلاً یه packet می فرسته و میگه "Iraq war began"
در غیر این صورت دیگه ساکت می مونه و منتظر میشه تا من سوال بپرسم
مثلاً من می گم "?how old are you" بعد بهم میگه که "older than you"

حالا اگر اولش من بگم که من آقای Y هستم، جواب های سرور فرق می کنه.

این چیز هایی که گفتم همه اش چرت و پرت بود و هیچ جمله ی انگلیسی رد و بدل نمیشه و فقط کاراکتر های عجیب هستند که این وسط همین منظور ها رو می رسونند مثلاً:

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

و این که سوکتیه نه http یی

---

تا اینجا رو داری؟

حالا می خوام این برای 500 یوزر همزمان هم جواب بده


تا اینجاش رو که پیش بریم تازه اصل مطلب رو می گم
نه، بذار الان بگم
این 500 تا یوزر باید بتونند با فاصله ی زمانی یا بدون فاصله با اون سرور ارتباط بر قرار کنند.
یعنی: Client + Server + 3rd Party Server


این سوکتی که من گفتم از نوع Client ه ها!
یه وقت اشتباه برداشت نکنی.

مرسی و ببخشید
منتظرم

_H2_
23-06-2008, 19:24
سلام

...دل نمی سوزونه. بچه ی خوبیه ها ولی داره کار درست...
بابا، بچه مردم میخواهد پول دربیاره! ماکسیما بخره! چه کارش داری؟! :31:

راستی همینطوری و بدون دلیل خاصی یاد "تکنیک برتر" افتادم، زمانی که من اینجا عضو شدم ایشان خیلی فعال بودند، ولی دیگه خبری نیست؟؟!!!نمیدانم پاقدم ما بوده؟؟؟ اخرین فعالیتش مربوط به سه ماه پیش است!!!!!

==========
خوب حالا مشکل کجا است؟؟؟!!!
شما اصلاً نتوانسته اید در دات نت با یک سوکت به یک سوکت دیگر وصل شوید و اطلاعات رد و بدل کنید؟؟؟؟
یا توانسته اید ولی در 500 تاش مشکل دارید و به خون ویندوز تشنه اید؟؟؟

dogtag
23-06-2008, 19:45
گفتم که من این رو با Php نوشتم (فکر نکن که فقط کد سوکت بود ها! تفسیر حرف های سرور هم بود که حجمش خیلی رفت بالا)
حالا می خوام مثل یه بچه ی خوب بشینم تو کلاس درس استاد H2 تا بهم یاد بده که چجوری:
1- سوکت برای اتصال 1 نفر درست کنم (فقط جنبه ی آموزشی داره)
2- چجوری 500 نفر رو متصل کنم

مرسی

Ultimator
23-06-2008, 21:58
بابا، بچه مردم میخواهد پول دربیاره! ماکسیما بخره! چه کارش داری؟!
:31::31::31: ! بذار کنکورمان رو بدیم ماکسیما و اینا خریدن پیش کش ! علم آموزی مهمتر از پروژه تحویل دادنه ! :31::31:
مسیح جان بابت پست نامربوط عذر میخواهم ! داشتم رد میشدم گفتم عرض ادبی بنمایم ! اگر سنگینی مینماید بفرما حذفش کنم !
من رفتم کنکور !
راستی سلام !

_H2_
25-06-2008, 00:00
سلام

! بذار کنکورمان رو بدیم
د نگرفتی داداش!
اتفاقاً چون این مطلب را میدانستم آن را گفتم، (خودتان در یک تاپیک دیگر گفته بودید!) کمی بیشتر فکر کنید متوجه میشوید که بی راه نگفتم! :31::46::21::3::blink:
==========
جناب dogtag:
توضیح کلی کمی طولانی میشود، در نتیجه تصمیم گرفتم تا مثالی برایتان حاضر کنم، که متاسفانه وقت نشد تکمیلش کنم.
انشا ا... فردا شب که برگشتم خانه، تکمیلش میکنم و برایتان میگذارم.:11:

با مفاهیم شی گرایی و چند ریختگی آشنایی دارید؟؟؟

چون یک جایش جون میده برای وراثت! ولی گفتم شاید کمی پیچیده به نظر برسد و از خیرش گذشتم.
یک برنامه exe است که یک Chat ساده متنی را بین کلاینت ها و سرور شبیه سازی میکند.
گرچه exe است ولی اصولش با asp.net فرقی ندارد، به نظرم برای شروع یادگیری طریقه استفاده از سوکت ها در دات نت، اینطوری ساده تر است.
اگر واقعاً این نمونه ساده را متوجه شوید و تک تک خطوطش را درک کنید و بتوانید خودتان بنویسید، گمانم کل مشکلاتتان با سوکت های دات نت حل شود، انشا ا...

تا فردا. :10:

dogtag
25-06-2008, 12:05
ممنون H2 جان
اگر مثالت خوب باشه که عالیه. چون اگر کدی رو خط به خطش رو نفهمم، یه جور هایی ازش بدم میاد!
اون وراثت و اینها رو هم احتمالاً بلدم. یه چیزی خوندم که توضیحاتی داده بود و این کلماتی که میگی هم توش بود :دی
احتمالاً چون اسم فارسی ه نمی دونم. آخه منبعم انگلیسی ه.

نتیجه ی تحقیقات خودم (که برای پیدا کردنشان فحش شنیدم و کتک خوردم) را می نویسم:

سوکت نویسی در Win App با Web خیلی فرق داره. حداقل به دلیل این که اگر بخوای Async Socket بنویسی، Win App تا زمانی که برنامه اجراست می تونه منتظر جواب بمونه ولی تو Web باید کار رو سریع تموم کنی و نتیجه رو اعلام کنی. (شاید یه حلقه ی بینهایت جواب بده)
بهم پیشنهاد شد که Windows Service بنویسم. چون محدودیت سرور ساید رو از بین می بره ولی نمی دونم اون رو چجوری نصب کنم و چجوری در برنامه ام ازش استفاده کنم.
با این حال نمی دونم که چجوری می تونم 500 تا سوکت Async رو با Windows Application درست کنم.
من تو PHP اینجوری کار کردم : با یه صفحه اسم طرف رو می گرفتم و با آجاکس می دادم به این صفحه ی سوکت دارم و از اون به بعد دیگه صفحه ی سوکت با بقیه ی جا ها هیچ ارتباط مستقیمی نداشت و این وسط یه DB داشتم که هر چیزی که می شد رو تو اون می نوشتم و برنامه ام مثلاً هر 30 ثانیه میومد DB رو بررسی می کرد تا ببینه کسی چیزی گفته یا نه. ولی اینجا احتمالاً روش بهتری هم هست.


الان بقیه اش یادم نمیاد. ولی شما لطف کن این 1 کار ما رو راه بنداز، ایشالله از خجالتت در میایم :11:

مرسی

_H2_
25-06-2008, 22:07
سلام


چون اگر کدی رو خط به خطش رو نفهمم، یه جور هایی ازش بدم میاد!

انشا ا... شرمندتان نشوم، هر سوالی در خصوص کد داشتید بپرسید.



اون وراثت و اینها رو هم احتمالاً بلدم.

من هم استفاده گردم، البته وراثت نیست، پلی مورفیزم است، به نظر من که ساده تر شده.
کد سرور و کلاینت را کاملاً مجزا و واضح در دو کلاسس نوشتم که با یک رابط مشترک توسط یک پنجره واحد مدیریت میشوند




سوکت نویسی در Win App با Web خیلی فرق داره

تا حدودی درست است و باید به نکات خاصی دقت شود، ولی در کل و حداقل در دات نت تفاوت فاحشی وجود ندارد و کلاسسها و متدها مشترک است، فقط باید به ریسمان اجرا کننده دقت داشت.






که Windows Service بنویسم

بد نیست، ولی یک نوع exe است ! سرور باید اختصاصی باشد و بعد هم باید فکر کرد که با توجه به کارتان WinService بهتر است یا WinApp .



در مورد 500 سوکت هم، فقط یک حلقه for ناقابل میخواهد تا به تعداد مورد نیاز دستور ساخت و اتصال را تکرار کند.
شما میخواهید در یک رایانه 500 سوکت کلاینت درست کنید؟
یا قرار است 500 کامپیوتر کلاینت به سرورتان متصل شوند؟

==========

در آخر لازم میدانم متذکر بشم که این مثال خیلی ساده است (exe اش 16 کیلو است) و هیچ مکانیسمی مقابله با خطایی در نظر گرفته نشده.
یکم کلی تر نوشتم تا برای دیگران هم قابل استفاده باشد.
باید حتماً اول نمونه سرور کانکت و آماده باشد و بعد کاینت ها متصل شوند.
نمونه سرور باید واحد باشد ولی تعداد کلاینت ها میتواند هر چندتا باشد.

انشا ا... با یک نگاه....

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

dogtag
25-06-2008, 22:34
واقعاً ممنون و شرمنده
می دونم که مجانی وقت گذاشتن برای دیگران یعنی چی. مخصوصاً وقتی که مثل من خنگ و تازه کار هم باشند!

من میخواهم در یک رایانه 500 سوکت کلاینت درست کنم.

فکر کنم مشکلی نباشه. چون یه سرور می تونه حداکثر 500 تا end point داشته باشه.

برای مثال ممنون. (شب کنکور دارم کد NET. آنالیز می کنم!!!!)

مشکل من با همین ریسمان ها و این جور چیز هاست.
یعنی نمیشه تو یه فایل aspx ، تعداد 500 کانکشن درست کرد؟ مثلاً از دیتابیس بخونه و هر وقت که تو فیلدی به نام command نوشته بود new X بره یه ریسمان درست کنه و یه کانکشن بده توش با نام آقای X و از اون به بعد مثلاً کامند ها اینجوری باشه X:Hi Server که اون رو بخونه و بفهمه که باید به سوکتی که تو ریسمان آقای X هست، جمله ی Hi Server رو بفرسته؟

_H2_
25-06-2008, 22:55
سلام
در دات نت هر کاری که عشقتان میکشد میتوانید انجام دهید، رایانه در خدمت شما است، از بیخ و بن!
چت میخواهید بسازید؟

_H2_
25-06-2008, 22:59
سلام


...شب کنکور دارم کد NET. آنالیز می کنم...

آخرش هم بلای من سرت در می آید و دیپلمه میمونی! فقط من اون موقع که جوون بودم(!) شب امتحانام میشستم کتابهای الکترونیک میخوندم.
بشین درس بخوان ، مگو چیست نمره، که سرمایه جاودانه است مدرک! (البته بعد از پارتی!) :31:

dogtag
26-06-2008, 11:44
ممنون از جوابت
حالا میشه با جزئیات بیشتر توضیح بدید؟

دارم اونی که دادی رو می خونم. ولی شما هم لطف کن این سوالات آخرم رو یه جوابی بده.

مرسی

----


چت میخواهید بسازید؟
از کجا فهمیدی؟ :دی

_H2_
27-06-2008, 15:33
سلام
میبخشید طول کشید، زیاد حال و حوصله .... سعی کردم متدهای کلیدی و اصلی را تشریح کنم. :11:
ولی با هر متد دیگری هم مشکل داشتید، مشکلی نیست! بپرسید..
ضمناً یک کم کد را تغییر دادم، در حد چند خط، پیشنهاد میکنم، مجدداً آخرین نسخه را دانلود کنید.


- کلاس System.Net.Sockets.Socket
اصلی ترین کلاسس مبنا جهت مدیریت سوکت ها است.

- کلاس System.Net.Sockets.TcpClient
یک سوکت را باز کرده و برای کار تحت پروتکل TCP/IP و به صورت کلاینت مهیا میکند.
متد شروع کار Connect
متد پایان کار Close
خصوصیتی که سوکت را برمیگرداند هم Client است

- کلاس System.Net.Sockets.TcpListener
یک سوکت را باز کرده و برای کار تحت پروتکل TCP/IP و به صورت سرور مهیا میکند.
متد شروع کار Start
متد پایان کار Stop
خصوصیتی که سوکت را برمیگرداند هم Server است
==============================
System.Net.Sockets.Socket
متد Receive جهت دریافت اطلاعات، با ریسمان جاری و به صورت بلوکه شده میباشد.
متد BeginReceive جهت دریافت اطلاعات، به صورت غیر همزمان و غیر بلوکه شده است.

متد Send جهت ارسال اطلاعات، با ریسمان جاری و به صورت بلوکه شده میباشد.
متد BeginSend جهت ارسال اطلاعات، به صورت غیر همزمان و غیر بلوکه شده است.

پارامترهای یکی از Overload های متد BeginReceive و Send را که در برنامه نمونه استفاده شده در زیر بررسی میکنیم، Receive و BeginSend هم همین پارامترها را دارند.
Send==========

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
این Overload متد Send، فقط یک آرایه بایتی میگیرد و آن را ارسال میکند، همه اطلاعات دیگر را باید به آرایه ای از بایتها تبدیل کرد؛ که در کد نمونه ما متن را با متد System.Text.Encoding.UTF8.GetBytes تبدیل کردیم.
BeginReceive==========

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
- پارامتر buffer یک بافر را برای ریختن اطلاعاتی دریافتی در آن تحویل متد BeginReceive میدهد.

- پارامتر offset نقطه شروع و size تعداد بایتهایی را مشخص میکند که متد BeginReceive اجازه دارد از buffer استفاده کند، در حالت عادی، offest صفر است و size همان مقدار گنجایش buffer است، یعنی متد مذکور میتواند از کل buffer استفاده کند.

- پارامتر socketFlags یک سری پرچم های بیتی را برای سوکت تنظیم میکند که معمولاً مقدار None کفایت میکند.

- پارامتر callback هم یک اشاره گر یا handler از تابعی است که باید در زمان اتمام دریافت، اجرا شود، میتوانید آن را مثل رویداد Click یک دکمه فرض کنید، یعنی هر زمان داده ای دریافت شود، این این متد اجرا شود.
در VB میتوان handler تابع یا به قول دات نت Delegate یک تابع را با دستور AddressOf به دست اورد.
این handler باید امضای AsyncCallback را داشته باشد، یعنی باید با کدی مشابه زیر تعریف شوده باشد.

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

پارامتر state بیشتر حالت اختیاری دارد و البته بسیار مفید است، این پارامتر یک مقدار را میگیرد، هر چه خواستید، یک Integer یا یک String یا هر Object دیگری و هیچ کاری با این مقدار انجام نمیدهد!!!!
وقتی کار دریافت اطلاعات تمام شد، و تابع callback اجرا شد، عین همین مقداری را که به state داده بودید در ar.AsyncState متد هدف callback تحویل میدهد.
این قابلیت برای تشخیص این چه دیتایی از کجا رسیده بسیار مهم است، گرچه شاید در کد کلاینت چندان فایده ای نداشته باشد.
ولی کد سرور را مد نظر بگیرید، متد callback که رسیدن اطلاعات را تشخیص میدهد، چگونه بفهد که این اطلاعات از کدام کلاینت آمده؟! و به خاطر کدام دستور BeginReceive که برای کلاینتی اجرا شده، حالا جوابی رسیده؟!
در این حال شما میتوانید در state، سوکت، ایندکس کلاینت، ip کلاینت و یا شی ای که اطلاعات کلاینت را در آن نگاه میدارید (در کد نمونه کلاسس دست ساز ClientItem) به BeginReceive پاس دهید تا بعد که متد مورد هدف callback اجرا شد، بتوانید تشخیص دهید به خاطر رسیدن دیتا از کدام کلاینت اجرا شده.

===
متد callback باید پارامتر ar As System.IAsyncResult را که دریافت کرده به متد EndReceive سوکت اولیه بدهید تا چرخه BeginReceive و EndReceive تکمیل شود.
متد EndReceive یک Integer پس میدهد که نمایانگر تعداد بایتهای دریافت شده است.
یعنی اطلاعات جدید دریافت شده از نقطه offest مشخص شده در BeginReceive شروع و به تعداد همین عدد Integer ادامه مییابد.

باید توجه داشت که یک بار صدا زدن BeginReceive، فقط یک دریافت اطلاعات را قفل میکند و برای دریافت مدام داده ها باید چرخه BeginReceive و EndReceive را مدام تکرار کرد.
==============================
System.Net.Sockets.TcpListener

شاید مهم ترین متد در این کلاسس BeginAcceptSocket باشد، این متد از نظر اصولی خیلی شبیه BeginReceive کلاس Socket است.
این متد به جای خبر دادن رسیدن دیتا، شما را از اتصال یک کلاینت جدید آگاه میکند.
یعنی در سرور با اجرای این متد، سوکت کلاینتی که بخواهد وصل شود، تشخیص داده شده و با اتصالش موافقت میشود.

متد مذکور فقط دو پارامتر میگیرد

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

که کار این دو پارامتر دقیق مثل پارامترهای مشابه در متد Socket.BeginReceive است، که پیش از این شرح داده شد، فقط handler پارامتر callback باید به متدی اشاره کند کهاتصال کلاینت های جدید را مدیریت میکند.
در این متد callback باید متد EndAcceptSocket با پارامتر ar As System.IAsyncResult ورودی صدا زده شود تا چرخه BeginAcceptSocket و EndAcceptSocket تکمیل شود.
متد EndAcceptSocket چرخه را تکمیل میکند و یک وهله از کلاسس Socket را باز میگرداند، که این نمونه یک اتصال به Socket نظیر کلاینتش است و هر چیزی که با این نمونه Socket ارسال و دریافت شود، فقط صرفاً به همان تک کلاینت مربوط میشود.
باید پس از تحویل گرفتن این نمونه Socket ، روی آن یک BeginReceive اجرا کنید، تا بتوانید به ارسالات کلاینت گوش فرا دهید.

dogtag
27-06-2008, 18:48
خیلی خیلی خیلی خیلی ممنون استاد
آقا اگه موافق باشی دیگه این تاپیک رو ادامه ندیم!
آخه اصلاً راضی نیستم که برای من، شما به زحمت بیافتید و انقدر تایپ کنید.
واقعاً شرمنده ام.

توضیحات بسیار مبسوط (اگه درست نوشته باشم :دی) و خوبی بود

امروز آنالیزش رو تموم می کنم.

البته تعریفات ابتدایی رو تقریباً خوب بلدم ولی مشکلم محدودیت های Server Side ه.

الان من اگر بخوام اون چت رو درست کنم باید چه کنم؟

اون برنامه که بهم دادید (حداقل قبل از آپدیت شدنش. آخه این جدیده رو هنوز ندیدم.) با باز کردن یک سرور و دو کلاینت، این اتفاق می افته:
کلاینت 1 که حرف بزنه، بدون فرق برای سرور، می نویسه که "فلان" (یعنی دقیقاً هر چیزی که گرفته شده رو می نویسه)
و بد تر از اون، سرور که یه چیزی رو بفرسته، هم کلاینت 1 و هم کلاینت 2، با هم دریافت می کنند

حالا سوالات اینه:
1- با Thread و اینجور چیز ها نمیشه سرور رو همیشه اجذا نگه داشت که فشار خیلی زیاد به سرور نیاد و با این پروژه ی من کار بکنه؟
2- چجوری بفهمه که کی، چی گفته (البته تو آموزش آخر تون، این رو گفتید. باید دقیق تر بخونمش)

_H2_
28-06-2008, 02:07
سلام


آقا اگه موافق باشی دیگه این تاپیک رو ادامه ندیم!

من مشکلی ندارم، و تا اتمام مشکلات شما در حد وقتم در خدمت هستم، ولی اگر شما مشکل دارید و نمیتوانید روی قضیه وقت بگذارید یا نمیخواهید مثل من.... تاپیک خودتان است، مختارید!




الان من اگر بخوام اون چت رو درست کنم باید چه کنم؟

اصل تفاوت در asp.net به دو چیز مربوط میشود
1- به محل نگه داری اشیا مربوط میشود که دیگر نمیتوان در داخل webpage ها باشد، باید تمام متغیرها اصلی یا به طور کلی نمونه کلاسس CClientChat و CServerChat را به مکان امنی مثل Appilication منتقل کنید.

2- اگر میخواهید پیغام های جدید دریافتی در صفحات aspx منعکس شود، حتماً میدانید که در هیچ پلتفرم تحت وبی نمیتوان با دستور سمت سرور، کلاینت را Refresh کرد، ولی میتوان با کد js (که اگر تلفیق با ajax شود، فوق العاده عالی میشود) به صورت تایمیک، صفحه به سایت مراجعه کند و در صورت وجود داده جدید، خود را آپدیت کند.




کلاینت 1 که حرف بزنه، بدون فرق برای سرور، می نویسه که "فلان" (یعنی دقیقاً هر چیزی که گرفته شده رو می نویسه)

اولاً که منظورتان را نمیفهمم، یعنی اون میگه، بادمجان، این باید بنویسه، سیب زمینی؟!
دوماً این فقط یک کد نمونه است، مثل این میماند که من یک کد MsgBox بنویسم که عبارت Hello را نشان دهد و شما بگویید، این خوب نیست، چون من میخواهم عبارت How Are You را نشان دهد!!!!!!!!!

کد دست شما است، شما برنامه نویس هستید، هرکاری میخواهید بکنید، مشکلی وجود ندارد، فراموش نکنید، باور کنید که شمائید که باید به رایانه خنگ بگویید چه کار کند، نه ان!



و بد تر از اون، سرور که یه چیزی رو بفرسته، هم کلاینت 1 و هم کلاینت 2، با هم دریافت می کنند

باز هم همان جوابتان میشود، شما برنامه نویس هستید! در اصل من خودم اینکار را با یک حلقه for انجام دادم (فایل CServerChat جدید، خط 62) یک حلقه ساده for که عمل send را برای تک تک کلاینت ها انجام میدهد، نمیخواهید؟ برش دارید! کار سختی نیست.

در واقع در کار سوکتی شما به یک خط ارتباط دو سویه بین کلاینت و سرور میرسید که تمام نقل و انتقالات دست شما است.
- حال مثلاً شما نیاز دارید تا سرور پیغامی را به تمام کلاینت ها بفرستد (مثل کاری که من کردم) می آیید و یک حلقه for میگذارید تا عمل ارسال برای همه انجام شود.
- یا نیاز پیدا میکنید، یک کلاینت بتواند برا یک کلاینت دیگر اطلاعات بفرستد و بگیرد، برای این کار هم سرور را میانجی میکنید، کلاینت اطلاعات را به سرور میفرستد و در بخش مشخصی از دیتا ها مشخص میکند که این بسته باید برای فلان یکی کلاینت ارسال شود، و کد سرور بسته را به کلاینت دیگر میفرستد، یعنی از این دست میگیرید و از آن دست به دیگری تحویل میدهد


مجدداً تاکید میکنم، شما یک ارتباط امن و کاملاً مشخص بین سرور و هر تک کلاینت دارید، که وقتی پیغامی فرستاده یا دریافت میشود به وضوح مشخص است از کدام کلاینت است و به راحتی میتوانید برای سادگی بیشتر به هر کلاینت یک ID عددی یا رشته ای هم نصبت دهید.
مثل یک تلفن فرض کنید، که بین هر نمونه کلاینت و سرور یک خط تلفن فعال وصل و آماده است و میتواند هر دیتای بایتی را رد و بدل کند، یک خط تلفن مشخص و ایزوله بین هر کلاینت با سرور. OK ؟؟؟؟




چجوری بفهمه که کی، چی گفته

در کد نمونه من برای هر کلاینت یک وهله از کلاسس دست ساز ClientItem را میسازم تا اطلاعات آن کلاینت را نگاه دارد، که در کد من فقط دو پارامتر اصلی یعنی Socket و Buffer نگاه داشته میشود، ولی شما میتوانید هر آیتمی به این کلاسس اضافه کنید مثلاً UserName یا FirstName یا LastDateTimeDialog یا هر چیز دیگری که بخواهید...
طبیعی است که این موارد اضافه را هم باید در اولین بار وصل شدن یک کلاینت پر کنید (فایل CServerChat جدید، خط 74) یا با هر روش دیگر، مثلاً میتوانید برای کدهای خودتان اینطور قرارداد کنید که پس از اتصال، اولین داده ارسالی یک String باشد که شامل UserName کلاینت باشد، و کلاینت به محض اتصال خودش این را ارسال کند....

اینها را که انجام دادید، دیگر فکر کنم قبول داشته باشید که داشتن مقدار ClientItem (و طبیعتاً متغیرهای داخلش) برای شناسایی کلاینت در هر زمان کافیست.

خوب هر زمان که داده جدیدی دریافت شود، کد نمونه جاری وهله ClientItem اش را به دست می آورد (فایل CServerChat جدید خط 102) به راحتی تمام اعضای ClientItem به محض رسیدن داده جدید در اختیار شما قرار میگیرد و شما میتوانید رویش عملیات مورد نظر خود را انجام دهید.




... Thread و اینجور چیز ها نمیشه سرور رو همیشه اجذا نگه داشت که فشار خیلی زیاد به...
به لطف دات نت زیاد هم نمیخواهد نگگران ایجاد ریسمان و مدیریت ان باشید.! وقتی از متدهای سری BeginXXXXXX و EndXXXXXX استفاده میکنید، در اصل (معمولاً) خود دات نت یک ریسمان دیگر ساخته و مسئول انجام عمل فوق الذکر میکند و این یعنی پردن کارها به ریسمان های دیگر.

فقط اگر قرار است کار زمان بری را با خود ریسمان درخواست کننده صفحه aspx انجام دهید، باید توجه داشته باشید که این ریسمان (بسته به تنظیمات web.config) یک timeout مشخصی دارند، که اگر ظرف این مدت کارشان تمام نشود و خروجی را برای دانلود و ارسال به مرورگر تحویل ندهند، ریسمان متوقف خواهد شد.

مثلاً من در کدم ارسال به تمام کلاینت ها از متد Send استفاده کردم، این متد کار را در ریسمان مجزا انجام نمیدهد و در اصل به مدت ارسال داده ها ریسمان میخوابد، کهع اگر این خواب را در تعداد کلاینت ها ضرب میکنیم، میبینیم که انجام عمل Send برای تمام اعضا، با همان ریسمان درخواست کنند صفحه aspx کار خوبی نیست و میتواند منجر به timeout و توقف ریسمان شود، مثلاً برای حل این مشکل میتوانید خودتان یک ریسمان جدید بسازید تا آن حلقه For شامل Send را اجرا کند یا اینکه به جای Send از جفت BeginSend و EndSend استفاده کنید، که برای هر ارسال کلاینت در حالت ایده آل از یک ریسمان مجزا استفاده میکند.
==========
فکر میکند من چند سال یا ماه یا .. طول کشید تا کد نویسی سوکتها را در دات نت یادبگیریم؟؟؟؟
فقط حدود 2 ساعت!
یعنی دو ساعت قبلبش هیچ نمیدانستم، و دو ساعت بعد، بدون هیچ فرد یا pdf یا کتاب و حتی بدون مراجعه به MSDN ، و فقط با امتحان کد و Object Browse توانستم کار تحت سوکتها را در دات نت یادبگیریم و حتی یک برنامه فیلم برداری از صفحه نمایش هم بنویسم، دلیلش هم فقط و فقط باور داشتن به سادگی مسئله و یک وقت گذاشتن سیر و بدون هواس پرتی دوساعته بود، بدون شک شما هم متوانید یار هر کسی که بخواهد و وقت بگذارد.

البته من به هیچ وجه نخواندن دروس کنکور را پیش نهاد نمیکنم، فردا نیایید بگید، این منو اغفال کرد!!!! :31:من چه کاره بیدم! :5:
==========
در آخر برای شما و بیشتر دوستان دیگر یاداوری میکنم که در حالت واقعی برای پیاده سازی یک چت انلاین و بدون exe در داخل یک سایت مشخص، هیچ نیاز به استفاده از Socket نیست.
یعنی در موردی که همه افراد چت کننده، بدون هیچ برنامه exe کمکی، وارد تک سایت مشخصی میشوند و چت میکنند. در این حالت استفاده از سوکت یعنی چرخواندن لقمه!

ولی خوب اگر جنبه آموزشی و یادگیری یا کارکردی متفاوت با چت داشته باشد، بحث فرق میکند...

موفق باشید.

dogtag
28-06-2008, 11:13
من مشکلی ندارم، و تا اتمام مشکلات شما در حد وقتم در خدمت هستم، ولی اگر شما مشکل دارید و نمیتوانید روی قضیه وقت بگذارید یا نمیخواهید مثل من.... تاپیک خودتان است، مختارید!
من که مشکلی ندارم. تازه از خدام هم باشه که یه استاد توپ گیرم اومده.


به محل نگه داری اشیا مربوط میشود که دیگر نمیتوان در داخل webpage ها باشد، باید تمام متغیرها اصلی یا به طور کلی نمونه کلاسس CClientChat و CServerChat را به مکان امنی مثل Appilication منتقل کنید.
فکر نمی کنم نیازی باشه. خب امنیت Web هم انقدر هست که بتونه کل کار رو ردیف کنه.


اگر میخواهید پیغام های جدید دریافتی در صفحات aspx منعکس شود، حتماً میدانید که در هیچ پلتفرم تحت وبی نمیتوان با دستور سمت سرور، کلاینت را Refresh کرد، ولی میتوان با کد js (که اگر تلفیق با ajax شود، فوق العاده عالی میشود) به صورت تایمیک، صفحه به سایت مراجعه کند و در صورت وجود داده جدید، خود را آپدیت کند.
می دونم. برای همین هم گفتم که از دیتابیس استفاده کنم.


اولاً که منظورتان را نمیفهمم، یعنی اون میگه، بادمجان، این باید بنویسه، سیب زمینی؟!
دوماً این فقط یک کد نمونه است، مثل این میماند که من یک کد MsgBox بنویسم که عبارت Hello را نشان دهد و شما بگویید، این خوب نیست، چون من میخواهم عبارت How Are You را نشان دهد!!!!!!!!!
منظورم رو بد رسوندم.
منظورم این بود که بتونه تشخیص بده که چه کسی این حرف رو زده و اسمش رو به buffer اضافه کنه و نشون بده.
که تو آخرین توضیحاتتون، کاملاً روشن کردید.


باز هم همان جوابتان میشود، شما برنامه نویس هستید! در اصل من خودم اینکار را با یک حلقه for انجام دادم (فایل CServerChat جدید، خط 62) یک حلقه ساده for که عمل send را برای تک تک کلاینت ها انجام میدهد، نمیخواهید؟...
آخ. ببخشید.
اصلاً نمی تونم کد رو آنالیز کنم. آخه تا میام برم سرش، 1000 تا کار برام پیش میاد.
ولی قول می دم که امروز تمومش مکن. (این خط، این هم نشون. تا سال دیگه هم تموم نمیشه :دی)


مجدداً تاکید میکنم، شما یک ارتباط امن و کاملاً مشخص بین سرور و هر تک کلاینت دارید، که وقتی پیغامی فرستاده یا دریافت میشود به وضوح مشخص است از کدام کلاینت است و به راحتی میتوانید برای سادگی بیشتر به هر کلاینت یک ID عددی یا رشته ای هم نصبت دهید.
از اونجایی که من زیاد با NET. و امثال هم کار نکردم و تازه دارم ASP.net 3.5 unleashed رو می خونم، ( تازه صفحه 120 ام :اسمایل ناراحت: ) میشه یه تیکه نمونه کد بدید که چجوری بهش ID بدم که بعداً بتونم با اون ID بهش چیزی بفرستم؟


جای Send از جفت BeginSend و EndSend استفاده کنی
آره. باید این کار رو بکنم.
(ولی مشکل اینجاست که بلد نیست. ولی الان که کد رو آنالیز کنم، یاد میگیرم)


فکر میکند من چند سال یا ماه یا .. طول کشید تا کد نویسی سوکتها ...
خب همه که مغزشون مثل شما نیست. خدا جلبک رو هم آفریده. جلبک هم دل داره، می خواد چت بنویسه :دی


فقط اگر قرار است کار زمان بری را با خود ریسمان درخواست کننده صفحه aspx انجام دهید، باید توجه داشته باشید که این ریسمان (بسته به تنظیمات web.config) یک timeout مشخصی دارند، که اگر ظرف این مدت کارشان تمام نشود و خروجی را برای دانلود و ارسال به مرورگر تحویل ندهند، ریسمان متوقف خواهد شد.
نمیشه مثل کانکشن، Packet الکی (خالی) بفرستی که time out نشه؟ یا نمیشه تو web.config اون رو بی نهایت کرد؟


در آخر برای شما و بیشتر دوستان دیگر یاداوری میکنم که در حالت واقعی برای پیاده سازی یک چت انلاین و بدون exe در داخل یک سایت مشخص، هیچ نیاز به استفاده از Socket نیست.
واما حرف ها من:
اینی که می خوام بنویسم چت بین اعضای سایت خودم نیست.
می خواستم نگم و آخرش که تموم شد، همه رو سولپلایز کنم.

بذار با شکل بگم که تو PHP چی کار کردم. احتمالاً همون کار رو باید تو NET. بکنم با این تفاوت که BeginReceive و اینها رو باید توش بذارم:

یوزر میاد تو صفحه ی index.php (قراره که همه کار تو یه صفحه انجام بشه. البته فقط User Interface ش)
بعد یه ارتباط با آجاکس درست برقرار میشه بین اون صفحه ای که یوزر توشه و یه صفحه که می تونه اطلاعات رو تو DataBase بریزه و ازش بخونه. (که باید با اون صفحه ی سوکت هامون یکی نباشه)
و Username و Password رو به سرور میفرسته ولی فقط با یک متغیر. همونجوری که در عکس هست.
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]

اون صفحه ی DB هم هیچ کاری رو داده ها انجام نمیده و مستقیماً می فرسته شون تو یه جدول به نام Requests
واسه یوزر یه پیغام میاد که "صبر کنید..."
و یه settimeout می ذاریم که هر 5 ثانیه 1 بار، وصل بشه به صفحه DB و ازش بپرسه که آیا من وارد شدم؟
اگر وارد شده بود، محتوای صفحه عوض میشه با صفحه چت. وگرنه ارور میده و تموم.

این وسط همه ی کارها می افته گردن اون صفحه ی سوکت هامون که من سمش رو ASP.net می گم (برای آسونی مطلب)

سرور باید بتونه هر 5 ثانیه، (اگه 5 ثانیه کمه، میشه بکنیم 30 ثانیه. برای فشار سرور) Database رو بخونه و ببینه که آیا درخواست جدیدی اومده، یا نه.
برای این کار من به جدولم یه ID دادم که Auto Increment باشه و بگم که

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
که هر ID رو که انجام میده، LastDoneID رو مساوی اون قرار بده برای دفعات بعد

بعد سرور با "," میاد اون درخواست رو پردازش می کنه و می فهمه که یوزر می خواد لاگین کنه.
User & Pass رو دستش می گیره ( اصل نکته اینجاست: )
یه ارتباط ناهمزمان (یا به قول فرنگی ها Async با همون BeginSend) با یه سرور دیگه برقرار می کنه.
به این شکل:
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]

حالا ممکنه از DB چیزی غیر از لاگین بخونه. مثلاً sendmessage,user1,user2,hi

باید اینجا یه فرقی باشه بین درخواست لاگین و فرستادن پیغام.
اگر درخواست لاگین بود، باید با یوزر طرف به عنوان ID بره یه دونه tcpClient درست کنه و اگر ارسال پیغام بود، بره سوکتی که با نام user1 درست شده رو پیدا کنه و باهاش مثلاً بفرسته که:

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

و وقتی که جواب نا همزمان از سرور ثالث اومد، اون رو یه پردازش بکنه و بذاره تو Database مثلاً تو جدول Response

حالا یوزری که لاگین کرده، هر 5 ثانیه از یه صفحه مثلاً DB2 می پرسته که چیزی نیومده؟
اون هم میره جدول Response که اون هم ID به صورت Auto Increment داره رو می خونه و جواب های جدید رو ور می داره و پردازش می کنه و به یوزر تحولی میده.



خب این طرح من بود که غیر از ناهمزمانی هاش، بقیه اش رو تو PHP پیاده کردم و با 1 یوزر کاملاً عالی جواب میده.
امیدوارم که خوب توضیح داده باشم.

دیگه ریش و قیچی دست خودت. ببینم چجوری با NET. می تونیم این رو درست کنیم.
مرسی یه تا اینجاش رو خوندی و یه خط در میون هم نخوندی.

باز هم ممنون

_H2_
29-06-2008, 22:44
سلام



...به مکان امنی ...

میبخشید، من منظورم را بد بیان کردم، منظورم اون امنیت نبود، یعنی توجه به خطرات امنیتی هم خوب است ولی منظور من آن نبود، منظور من امنیت خاطر باید از بین نرفتن اطلاعات بود، مثلاً میدانید که داده های داخل webpage ها بعد از اتمام رندر html از بین میرود، یا اطلاعات Session و Cookie و Cache و... که میدانید، هیچ حساب و کتاب و اطمینانی به حفظشان در رجوع بعدی نیست.

ولی Application یا Database این امنیت خاطر را دارد که دفعه بعد که مراجعه کنید، داده سر جایش است.



اولاً که منظورتان را نمیفهمم، یعنی اون میگه، بادمجان، این باید بنویسه، سیب زمینی؟!

باید اعتراف کنم (تا گناهم سبک شود!) که فهمیدم منظورتان چی بود ولی میخواستم کمی بحث را .....
معلوم بود که شما نگران ان username کوچک در کنار درج پیغامها هستید.
جواب سوالات بیشتر در قسمت "دوماً" بود.!


... همه که مغزشون ....

این همه تایپ کردم، در سه عبارت، سه بار تاکید کردم ... آن وقت شما باز .... :13::2:
به نظز من استعداد همان علاقه است.



نمیشه تو web.config اون رو بی نهایت کرد؟

این کار اصلاً درست نیست، و میتواند یک نقطه ضعف در کارائی و امنیت باشد.

به راحتی میتوانید یک ریسمان مجزا را به کار مورد نظر اختصاص دهید، خیلی ساده است. New و Start !!!



...بین اعضای سایت خودم نیست...

اون نکته بیشتر برای دیگران گفتم، همانطور که در متنش هم اشاره کردم، که شاید کس دیگری این مطالب را بخواند و تصورات اشتباهی کند.


...میشه یه تیکه نمونه کد بدید که چجوری بهش ID بدم ....

انشا ا...
حقیقتش دیرتر به پستتان جواب دادم، امیدوارم بودم که امروز بتوانم چیزی حاضر کنم، که متأسفانه وقت نشد... شرمنده، سعی میکنم نمونه جدیدی تکمیل کنم.

موفق باشید.

dogtag
29-06-2008, 23:04
آقا این دفعه چقدر جوابت کوتاه بود :دی

ممنون که وقت می ذاری

منتظر نمونه هستم

_H2_
03-07-2008, 00:07
سلام
میبخشید طول کشید، هر کاری کردم، وقتم خالی پیدا نکردم....
نمونه جدید، کامل نیست
ولی دیدم اگر بخواهم صبر کنم تا کاملش کنم، شاید خیلی....
البته چندان هم ناقص نیست، بهتر است ببینید.
کلاینتها بدون هیچ مشکلی میتوانند با هم ارتباط داشته باشند.

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

موفق باشید.

dogtag
03-07-2008, 14:27
ممنون
الان دانلودش می کنم

sari-1369
03-04-2009, 14:04
سلام
میبخشید طول کشید، هر کاری کردم، وقتم خالی پیدا نکردم....
نمونه جدید، کامل نیست
ولی دیدم اگر بخواهم صبر کنم تا کاملش کنم، شاید خیلی....
البته چندان هم ناقص نیست، بهتر است ببینید.
کلاینتها بدون هیچ مشکلی میتوانند با هم ارتباط داشته باشند.

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنیدموفق باشید.



متأسفانه در حال حاضر فایل مورد درخواست شما برای دانلود موجود نیست !
این مسئله ممکن است موقتی یا دائمی باشد و یا به علت عدم استقبال و دانلود از آخرین تاریخ دانلود باشد.



:13::41::19:

_H2_
03-04-2009, 14:13
سلام
شما میتوانید آخرین نسخه را همراه با PDF فارسی از لینک زیر دانلود کنید:
h02.ir/Download.aspx?File=SampleSocketChat.zip

تاپیک:
forum.p30world.com/showthread.php?t=276352

arshinsystem
17-04-2010, 17:50
سلام دوستان
من تازه در اين سايت ثبت نام كردم و از اين تاپيك خيلي خوشم اومد چون يكي از مشكلات اصلي من بود و هست.
من چند تا سوال دارم:
اول اينكه من يه برنامه تحت وب نياز دارم كه يه سري دستورات به يك application بر روي يك سرور داده و جواب اون رو روي سايت نمايش بده. مثلا وب ميگه سلام و جواب مياد عليك سلام كه اين جواب بايد روي سايت نمايش داده بشه.
برنامه اي كه من نوشتم اولين پيغام رو درست ميفرسته و جواب هم برميگرده ولي اولا نميتونم جواب رو روي صفحه نمايش بدم كه واسه اين كار مجبور شدم پيغام رو روي يك فايل ذخيره كنم و بعد تو تايمر صفحه رفرش بشه كه اصلا از اين كار خوشم نمياد.
ثانيا مشكل در پيغام فرستادن بعدي هست. وقتي پيغام اول ميره و صفحه رفرش ميشه، تمامي پيغامها ريسيو ميشن ولي واسه فرستادن پيغام جديد ميگه كانكشن بسته است و وقتي كانكشن رو دوباره باز ميكنم يك كانكشن جديد ايجاد ميشه و همه چي بهم ميريزه.
ميشه اولا خواهش كنم يه مثال برام بفرستيد و ثانيا بهم بگيد مشكل من كجاست؟
واقعا ممنون ميشم

arshinsystem
18-04-2010, 08:40
باز هم سلام
گفتم بهتره كد برنامه ام رو براتون بفرستم اونجوري بهتر ميشه نظر داد


Imports System
Imports System.Text
Imports System.Net
Imports System.Net.Sockets
Imports System.IO
Partial Class WebForm1
Inherits System.Web.UI.Page
Dim Client As New TcpClient
Dim BufferSize(Client.ReceiveBufferSize - 1) As Byte
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Client.Connect("127.0.0.1", 80)
SendMessage("Hello")
Client.GetStream().BeginRead(BufferSize, 0, BufferSize.Length, AddressOf ReceiveMessage, Nothing)
End Sub
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
SendMessage("Hello2")
End Sub
Public Sub SendMessage(ByVal message As String)
Try
Dim netStr As NetworkStream = Client.GetStream()
Dim Data As [Byte]() = System.Text.Encoding.ASCII.GetBytes(message)
netStr.Write(Data, 0, Data.Length)
netStr.Flush()
Catch ex As Exception
Console.WriteLine(ex.ToString())
End Try
End Sub
Public Sub ReceiveMessage(ByVal ar As IAsyncResult)
Dim bufferLength As Integer
Dim message As String
Try
SyncLock Client.GetStream
bufferLength = Client.GetStream().EndRead(ar)
End SyncLock
If bufferLength < 1 Then
Client.Close()
End If
message = System.Text.Encoding.ASCII.GetString(BufferSize, 0, bufferLength).ToString()
Console.WriteLine(Client.Client.RemoteEndPoint.ToS tring() + "-> " + message)
Client.GetStream().BeginRead(BufferSize, 0, BufferSize.Length, AddressOf ReceiveMessage, Nothing)
Catch ex As Exception
Console.WriteLine(ex)
Client.Close()
End Try
End Sub
End Class

تو كد بالا پيغام اول كه زمان لود صفحه هست درست منتقل ميشه و برنامه شروع به گرفتن جوابها ميكنه.
تا اينجا درسته ولي اولا پيغام دوم (Hello2) وقتي ميخواد Send بشه ميگه كانكشن بسته است. درحالي كه كانكشن بر روي برنامه سرور بازه. وقتي دوباره كانكت ميزنم تعداد كانكشنها بر روي برنامه سرور ميشه ٢ تا و الي آخر.
مشكل دوم اينه كه پيغامي كه تو receive message مياد كه تو متغير message نگهداري ميشه رو نميتونم روي صفحه وب نمايش بدم. از delegate هم استفاده كردم ولي نشد.
ممنون ميشم راهنماييم كنيد.

_H2_
18-04-2010, 21:18
سلام

اول اينكه من يه برنامه تحت وب نياز دارم كه يه سري دستورات به يك application بر روي يك سرور داده و جواب اون رو روي سايت نمايش بده. مثلا وب ميگه سلام و جواب مياد عليك سلام كه اين جواب بايد روي سايت نمايش داده بشه.

توضیحاتتان ناقص است و محیط و نحوه استفاده شما را مشخص نمیکند.

آیا چیزی مشابه چت در یک سایت میخواهید راه اندازی کنید؟
برنامه winapp که ندارید بخواهد به سایتی وصل شود (چون انوقت نمایش در سایت بی معنی میشود!) ؟

اگر چیزی مشابه چت در خود یک سایت میخواهید اصلاً نیازی به برنامه نویسی سوکت ندارید!
شما با کمک Ajax و برنماه نویسی عادی ASP.Net می توانید این کار را انجام دهید.
یک سایت که برای ارتباط با خودش نیازی به سوکت ندارد.

بهرحال من هنوز متوجه نشدم طرح دقیق شما چیست و با کاربر چطور رابطه برقرار میکند.

=====

لازم به ذکر است که بد هم نبود یک تاپیک مجزا و جدید در سطح انجمن میزدید ...
شب خوش.

arshinsystem
19-04-2010, 08:09
سلام H2 جان
از جوابتان ممنونم، واقعيتش طرح اصلي من گرفتن قيمت ارزها از بانكهاي خارجي هست. مثل همون چيزي كه در فاركس وجود داره.
براي اين كار كدي از نوع string وجود داره كه وقتي اون رو به آي پي و پورت مورد نظر كه بانك تعريف كرده ميفرستي در جواب قيمت ارز براتون فرستاده ميشه. همينطور دستورات ديگري در رابطه با ميزان معامله و ... هم وجود داره كه با فرستادن اونها جوابها بر ميگرده.
اين كار رو با Application به راحتي انجام ميدم و مشكلي نداره يعني هرچيزي كه ميفرستم جواب به درستي برميگرده ولي هدف من اينه كه اين اطلاعات رو بر روي صفحه وب سايت نمايش بدم.
برنامه اي هم كه با asp.net نوشتم تا حدودي اين كار رو ميكنه ولي چندتا مشكل داره.
اول اينكه وقتي يك tcpclient ايجاد ميكنم و كانكشن رو برقرار ميكنم اولين string من به راحتي فرستاده ميشه و بعد از اون برنامه به حالت BeginRead سوكت ميره. خب تا اينجا همه چي درسته و جواب هم به درستي از طرف بانك برميگرده و خونده ميشه. ولي اين جواب رو نميتونم رو صفحه وب نمايش بدم. ميدونم كه بايد از Delegate استفاده كنم ولي نميتونم جواب بگيرم. نميخوام جواب رو هم به صورت فايل يا چيز ديگه اي save كنم چون بعضي از جوابها محرمانه و فقط مخصوص اون كلاينت خاص هستش.
مشكل دوم اينكه براي فرستادن String بعدي پيغام ميده كه كانكشن بسته است. در حالي كه كانكشن بازه و پيغامهاي بعدي كه از طرف بانك ميان خونده ميشن يعني انگار كانكشن من فقط در حالت خوندن پيغامها قرار ميگيره و من ديگه هيچ دسترسي يه اون كانكشن ندارم و مشكل اينه كه حتي نميتونم ببندمش و دائما سرور من در حالت خوندن پيغامها قرار ميگيره. وقتي هم كه مجدد اين كار رو ميكنم تعداد كانكشن بر روي بانك ميشه دوتا. يعني كانكشن قبلي من همون طور باز مونده و داره جوابها رو ميگيره.
نميدونم تونستم منظورمو برسونم يا نه.
در ضمن من بخاطر جوابهاي بسيار زيبايي كه به دوست قبليمون در اين تاپيك داديد خواستم كه بحث قبلي كامل بشه و اگر صلاح بدونين تاپيك جديد ايجاد كنم.
با تشكر فراوان - فقط نارمك :31:

_H2_
19-04-2010, 21:16
سلام

خوب پس استفاده شما از سوکت منطقی بوده.
اگر مایل بودید مثال و pdf ای در خصوص برقراری ارتباطات سوکتی میتوانید در تاپیک زیر پیدا کنید:
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]

=====


ولي اين جواب رو نميتونم رو صفحه وب نمايش بدم
راحت ترین راه برای این مشکل برقراری ارتباط سوکت با همان ریسمان صفحه aspx و تحت همان صفحه است.


براي فرستادن String بعدي پيغام ميده كه كانكشن بسته است
راه حل این یکی دقیقاً برعکس قبلی است!
یعنی سوکت شما نباید تحت ریسمان و دامین کاری همان aspx اجرا و باز شود.

=====

خوب دو تا مشکل دارید که جواب هر یک مخالف دیگری است ولی مشکلی وجود ندارد یک راه حل شرطی و یک راه حل قطعی دارد.

الف) راه حل شرطی اول:
من با هدر های ارتباطی سهام شما آشنا نیستم و برای همین گفتم شرطی ...
اگر لزوم Connect بودن سوکت برای ارتباطات بعدی (همان سوال و جواب خودتان) مهم نیست...
- Timeout زمان کاری ریسمان درخواست های [ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ] را افزایش دهید.
- سوکت را با دستورات Using در همان ریسمان و محیط کاری فایل aspx باز کنید و داده را با Send فرستاده و جواب را با Read بگیرید را سوکت را کلاً ببندید و تمام. (توجه کنید نگفتم BeginSend و BeginRead)

پس اگر ارتباطات شما از نظر سرور وابسته به تبادلات قبلی نیست، هر بار سوکت را باز کنید و سوالتان را بپرسید و ببندید.

ب) راه حل نهایی:
ولی در برخی ارتباطات Connect بودن سوکت در کل ارتباطت مهم است و اطلاعات مبادله شده قبلی روی مبادلات جدید تاثیر خواهد داشت.

راه حل قطعی و خوب و کامل این قضیه آنجا است که ...
- شما یک ماژول جامع ارتباطلات غیر همزمان مخصوص کار ناهمران با ASP.Net و Ajax طراحی کنید.
- کلاس ماژول شما باید قابلیت مدیریت همزمان چندین مکالمه جداگانه Server-Client را داشته باشد.
- و با کمک دستورات lock و synclock مناسب قابلیت کامل استفاده و دسترسی همزمان از چندین ریسمان مختلف را داشته باشد.
و ...

یعنی چیزی شبیه این الگو ...
1) شما در این ماژول جامع متدی برای ارسال اطلاعات به صورت نا همزمان خواهید داشت که اطلاعات ارسالی را میگیرد و فقط یک عدد int یا long و... به عنوان کد پیگیری مانند پس میدهد...
(مشابه مکانیزم خود ویندوز در API های دسترسی به فایل ها و رجیستری و... که پس از باز کردن مدخل یک کد اشاره گر 32 یا 64 بیتی برای اعمال بعدی پس میدهد)

2) ریسمان صفحه aspx منتظر ارسال کامل اطلاعات و دریافت پاسخ و... نخواهند ماند و کد اشاره گر یا پیگیری یا هر اسم دیگر را گرفته و به کدهای javascript برای ارتباط Ajax تحویل میدهد.

3) کدهای javascript برنماه در کلاینت در یک پریود زمانی مدام به سرور و یک [ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ] مشخص که برای این منظور در نظر گرفته شده وصل میشود و سعی میکند کد اشاره گر یا پیگیری و... را که دارد بدهد و جواب را اگر آماده است بگیرید و نمایش دهد.
(میتوان از کنترلر Ajax-Timer خود asp.net هم استفاده کرد.)

4) برای مکالمات مرتبط بعدی و بستن نهایی ارتباط و... هم از همان هندلر یا اشاره گر یا کدپیگیر اولیه استفاده خواهد شد و با دادن این کد ماژول مرکزی در Collection ای دارد به نمونه سوکت و بافر و... همان ارتباط دسترسی پیدا خواهد کرد و...

5) اگر کدهای ان عدد اشاره گر یا پیگیری پشت سر هم هستند میتوان برای امنیت بیشتر و جلوگیری از شنود ارتباطات توسط یک فرد خاص یک عدد password شانسی را هم برای هر ارتباطات در کنار کد مورد بحث قرار داد.

و...

توضیحات شاید به نظر زیاد بیاید ولی اگر درک کنید و اطلاعات مناسب از برنامه نویسی دات نت داشته باشید، کار چندان مشکلی نیست و حتی شاید با یک روز وقت (6 یا 7 ساعت) هم بتوان نمونه هسته و مازول اصلی مناسب و خوبی نوشت.

=====

شب بخیر.

dogtag
20-04-2010, 13:49
سلام بر این تاپیک قدیمی! :دی

(الان که دارم می خونم، می بینم چقدر اون زمان ها دات نت بلد نبودم! :دی)

البته الان دارید جواب این دوستمون رو می دید ولی با اجازه من هم بپرسم که حرف های قبلی مون تکمیل بشه.

تمام چیزی که من اون زمان می خواستم، همین "راه حل نهایی" شما بود.

اما خب مشکل پیاده سازی اش ه!
شما وقتی 1 درخواست با Ajax به یه فایل ASP.net می دید و اون بهتون یه ID میده، کار تموم میشه.
حالا اگر جواب درخواست رو بخواید، باید 1 درخواست دیگه با Ajax به اون صفحه بفرستید و ID رو بهش بدید تا مثلاً بگه که نتیجه مطلوب رو بدست آورده یا نه.
اما نکته اینجاست که این درخواست دوم دیگه به اون فایل قبلی فرستاده نشده و یه نمونه ی جدید از اون فایل اجرا شده!
سوکتی هم که قرار بوده با سرور ثالث Connect بمونه و تبادلات رو انجام بده، تو ریسمانی ه که با اولین فراخوانی فایل، ساخته شده!
و دیگه نمیشه بهش دسترسی داشت!

میشه این روش رو پیاده کنید؟

ممنون

arshinsystem
24-04-2010, 12:08
سلام
واقعا از توضيحاتتون ممنونم. كلي مارو شرمنده كرديد.
تقريبا ٦٠% توضيحاتي كه داديد رو فهميدم و بعضي چيزها رو نفهميدم. آخه من هم مثل دوست قديميمون در دات نت مخصوصا تحت وب خيلي كم تجربه ام. من در اصل برنامه نويس Application تو دلفي هستم ولي الان به شدت نياز به اين صفحه تحت وب دارم.
من صفحه وب خودم رو ماي وب اسم ميذارم و سروري كه اطلاعات رو به من ميده سرور بانك اسمشو ميذارم.
موضوع اينجاست كه من ميبايست يك كد براي شناسايي از ماي وب به سرور بانك از طريق سوكت بفرستم مثلا ميگم "قيمتها" و بعد از اون سرور بانك شروع به فرستادن قيمتها ميكنه. اين روند تا زمان بسته شدن صفحه ماي وب من ميبايست ادامه پيدا كنه.
قسمت دوم اينه كه من در حين اينكه سرور بانك قيمتها رو براي من ميفرسته نياز به اين دارم كه دستورات ديگه اي از ماي وب بفرستم مثلا بگم "قيمتها بر اساس ريال" و اينجاست كه گير ميكنم.
تو حالت اول يه كانكشن ايجاد ميكنم و دستور اول فرستاده ميشه. بعد هم ماي وب شروع به گرفتن اطلاعات از سرور بانك ميكنه. براي اينكه بتونم اطلاعات رو روي صفحه نمايش بدم از xml و تايمر استفاده كردم كه بد نبود و جواب داد.
ولي حالا كه ميخوام پيغام دوم رو بفرستم ديگه كانكشن بازي روي ماي وب وجود نداره، برام عجيبه كه پس چطور پيغامها از طرف سرور بانك مياد؟
حالا يك كانكشن جديد ايجاد ميكنم و پيغام جديد رو ميفرستم ولي سرور بانك اينو بعنوان كانكشن شماره ٢ ميشناسه چون از نظر سرور بانك كانكشن قبلي هنوز بازه. بخاطر همين يه كم مشكل پيدا ميكنم.
و مشكل آخر اينه كه وقتي من ماي وب رو ميبندم هنوز سرور بانك داره قيمتهاشو ميفرسته. نميدونم چرا كانكشنم بسته نميشه؟
كدي كه تو بالا نوشتم اين اشكالات رو داره. درضمن لينك دانلود شما هم خطا ميده و نتونستم دانلود كنم.
ممنون

arshinsystem
28-04-2010, 17:42
سلام
من هنوز نتونستم مشكلمو حل كنم
خواهشا فقط يه example تحت وب واسه ارسال و دريافت از طريق سوكت به من بديد و اينكه اين كار فقط با يك كانكشن باشه و بتونم كانكشن رو هر وقت خواستم disconnect كنم.
ممنونم

_H2_
03-05-2010, 00:44
سلام


میشه این روش رو پیاده کنید؟

خیلی واضح است که این اطلاعات و اشیا باید در محلهای static و یا شی Application و یا Cache نگه داری شود.
اصلاً به همین دلیل گفتم که به یک id نیاز داریم تا ajax ان id را بدهد و اطلاعات و آخرینت وضعیت را بگیرید.

اگر قرار بود همه چیز با همان ریسمان های خودشان و در محدوده دید خودشان نگه داری شود که id نمیخواست.
در واقع اطلاعات وضعیت و سایر اطلاعات مورد نیاز در یک ساختار Dictionary مانند در مکانی عمومی نگه داری میشود که کلید ان همان id است و در خواست های Ajax از ریسمان های مختلف می آیند و به این Dictionary ارجاع میدهند و آخرین دیتای موجود را میخوانند.

در دیتا وضعیت در یک struc ذخیره شده باشد خود ریسمانی که مسئول پردازش اولیه این درخواست و مدیریت سوکت هم است باید id را بداند و با هر مرحله تغییر و پیشرفت خانه و سطر Dictionary مورد نظرز را به روز کند.
ولی اگر دیتا در یک class ذخیره شده باشد چون class ها ساختار اشاره گری دارند و در حافظه هیپ هستند ریسمان مسئول پردازش ریسمان فقط وهله همان class دیتا را دارد و فیلدهای ان را با هر تغییر به روز میکند.



ولي حالا كه ميخوام پيغام دوم رو بفرستم ديگه كانكشن بازي روي ماي وب وجود نداره، برام عجيبه كه پس چطور پيغامها از طرف سرور بانك مياد؟
حالا يك كانكشن جديد ايجاد ميكنم و پيغام جديد رو ميفرستم ولي سرور بانك اينو بعنوان كانكشن شماره ٢ ميشناسه چون از نظر سرور بانك كانكشن قبلي هنوز بازه. بخاطر همين يه كم مشكل پيدا ميكنم.

یعنی شما میفرمائید در کلاینت connection بسته شده در حالیکه سرور هنوز ان را باز میداند؟



و مشكل آخر اينه كه وقتي من ماي وب رو ميبندم هنوز سرور بانك داره قيمتهاشو ميفرسته. نميدونم چرا كانكشنم بسته نميشه؟

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



حالا يك كانكشن جديد ايجاد ميكنم و پيغام جديد رو ميفرستم
... اينكه اين كار فقط با يك كانكشن باشه و بتونم كانكشن رو هر وقت خواستم disconnect كنم ...

در کل برای تحت وب و Asp.net این را پیشنهاد میکنم.
یعنی اینکه هر سوکت را خیلی سریع باز کنید و یک کار را انجالم دهید و در اولین فرصت سوکت را ببندید.
چون ذات برنامه های وبی، فضای مطمئنی برای نگه داری یک شی به طور زنده در حافظه ندارد.



درضمن لينك دانلود شما هم خطا ميده و نتونستم دانلود كنم

از این هاستینگ درپیت است! در ساعت دیگر و متفاوت سعی کنید دانلود کنید.

[quote]
خواهشا فقط يه example تحت وب واسه ارسال و دريافت از طريق سوكت به من بديد
[/.quote]
متاسفانه و با شرمندگی بسیار باور بفرمائید فرصت این یکی را ندارم.
الآن هم اگر ملاحظه کنید متوجه میشوید ساعت از یک و نیم بامداد هم گذشته که وقت کردم انلاین شوم و تازه شرمنده چند نفر از دوستان هم هستم که پیام خصوصی هایشان بی جواب مانده ...

سوال را شاید اگر بلد باشم، فرصت کنم جواب دهم ولی سمپل و پروژه و... :11::11::11::11::11:

=====

احتمالاً قبلاً گفتم ولی خودم یادم رفته چی گفتم ...
بحرحال یاد اوری میکنم که اگرکه سرور و کلاینت وب از خودتان و تحت کنترلر خودتان است از پروتکل های سطح بالاتر استفاده کنید که کنترلر جزئیات بیشتر بر عهده سیستم عامل و فریم ورک و سایر برنامه ها باشد کد شما خیلی کوتاه و مختصر تر شود ...

مثلاً در ساده ترین شکلش میتوانید اجازه دسترسی به بانک SQLServer سرور را به کلاینت هم بدهید.
یا حداقل از یک وب سرویس استفاده کنید و یا از یک [ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ] که فایل xml یا rss خروجی بدهد استفاده کنید و...

شب بخیر.

arshinsystem
03-05-2010, 13:42
سلام
واقعا شرمنده ام كه تا اين وقت شب مجبور شديد جواب منو بديد.
از توضيحاتتون واقعا ممنونم.
از توضيحاتتون يه چيزايي دستگيرم شد ولي متاسفانه من تو دات نت خيلي ضعيفم.
يه جورايي موفق شدم جواب بگيرم ولي مشكل بسته شدن كانكشن وجود داره.
فرض كنيد من يك tcpclient ايجاد ميكنم بنام test و با اون پيغامم رو ميفرستم. تا اينجا كانكشن بازه و رو سرور هم ميبينم كه بازه و به راحتي هم disconnect ميشه.
حالا برنامه ميرسه به قسمت BeginRead ، خب هنوز كانكشن بازه ولي از بعد از اين دستور حالا ديگه نه ميتونم پيغامي بفرستم نه ميتونم test رو ببندم چون ميگه كانكشن شما بسته است.
رو سرور كه نگاه ميكنم ميبينم كانكشن بازه و اگر از طرف سرور پيغامي بفرستم كلاينت دريافت ميكنه.
نميدونم چه اتفاقي ميفته؟
واقعا شرمنده از اينكه اينقدر وقتتون رو ميگيرم
با تشكر.

_H2_
25-05-2010, 19:59
سلام
مشکل فعلی شما به دلیل تز حوزه خارج شدن و پاک شدن کلاس page جاری است.

کلاس page مکان مناسبی برای نگه داری طولانی مدت متغییرها نیست.

قبلا هم کلیاتش را خدمتتان عرض کردم...
شما نیاز به یک کلاس مجزا جهن مدیریت کل این ارنباطات دارید.
از سایر page ها فقط بای متدهای این کلاس اجرا شود.
اشاره گر این کلاس باید جهت عمومی بودن و از حوزه خارج نشدن و عدم جمع اوری توسط garbage، باید به صورت vb.shared یا cs.static و همچنین در شی Application تعریف شود.

خیلی سعی کردم وقتی بگذارم و کد کاملتری برایتان بگذارم، ولی واقعاً و با شرمندگی کاملتر از این فرصت ندارم ...
به متدهای این کد دقت کنید و روابط بین انها را درک کنید و سعی کنید جاهای خالی که با ...// مشخص شده را با کدهای مناسب پر کنید.
به نظر من که این اسکلت بندی، کاملاً چهارچوبی را که بارها سعی کردم برایتان تشریح کنم نشان و به نظرم خودم خیلی واضح است!

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

اگر این کد تکمیل شود با دستوری مثل این میتوانید یک اطلاعات را به IP+Port ای خاص ارسال کنید و هندلر عددی (چیشری شبیه کلید یا شماره پیگیری) برای دفعات بعدی بگیرید که با ان هدلر عددی میتوانید مجدد به همان مقصد قبلی اطلاعات ارسال کنید یا اطلاعات رسیده از همان مقصد را ردیافت کنید.
به راحتی میتوانید پس از اولین درخواست این هندلر عددی را در ViewState یا Session و... کاربر قرار دهید و Send و Receive را با داشتن آن انجام دهید ...
کدهایی مثل اینها:

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
میبینید که استفاده بسیار ساده و روشن و شفافی دارد.

این روش پیاده سازی مشکل از حوزه خارج شده و جمع آوری را هم ندارد.
ولی بحرحال برنامه شما در حوزه WebApp و از ریسمان اولیه IIS اجرا میشود.
بدیهی است که ...
1) شامل مجوزهای تایین شده برای دامین سایت شما میشود.
2) IIS و Framework2,3 اگر برای مدتی هیچ فردی به سایت شما متصل نشود و هیچ درخواستی به سایت شما نرسد در جهت افزایش بازدهی سرور و نیز کارکرد بهتر سایت خود شما کلاً سایت شما را از RAM خارج و Down میکنند.
(البته راه حلی در Framework4 در نظر گرفته شده)

در نتیجه نیتوانید انتظار داشته باشید وقتی که کاربری هم درسایت شما نیست، اجرای کدها و دستورات برای مدت زیادی ادامه یابد.

=====

اگر سوالی در مورد متدهای فوق و کاری که انجام میدهند یا باید انجام بدهند داشتید، مطرح بفرمائید.
شاید کمی کار داشته باشم ولی یا جایی که وقت و سوادم اجازه دهد در خدمت هستم.
موفق باشید.