PDA

View Full Version : سوال: System.Net.Sockets.TcpClient یا winsock ؟



hamidhws
چهارشنبه 31 خرداد 1391, 09:24 صبح
سلام دوستان
میخواستم بدونم توی دات نت 2010 (یا 2012) برای socket programming بهتره از winsock استفاده کرد یا کلاس های آماده دات نت؟

اگه اشتباه نکنم میشه کارهای winsock رو با System.Net.Sockets.TcpClient و System.Net.Sockets.Tcplistener
انجام داد (اگه اشتباه میکنم لطفا راهنمایی کنید)

حالا مشکلم اینجاست با کلاس دات نت اینه که مثلا از کجا بفهمم که وقتی دستور connect رو زدم دقیقا چه زمانی کانکشن وصل میشه ؟و مابقی دستورات...آخه نتونستم event ی توی این کلاس پیدا کنم!

hamidhws
چهارشنبه 31 خرداد 1391, 10:53 صبح
کسی اطلاعی نداره؟

Saeed_m_Farid
چهارشنبه 31 خرداد 1391, 13:20 عصر
سلام

سوال اول شما به شرطی که حوصله جوابش رو داشته باشین، یه سوال تئوری هست! تو دات نت بحای Winsock (http://msdn.microsoft.com/en-us/library/windows/desktop/ms740673%28v=vs.85%29.aspx) از System.Net.Sockets.Socket (http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.aspx) استفاده میشه : همونطورکه میدونید Winsock (http://msdn.microsoft.com/en-us/library/windows/desktop/ms740673%28v=vs.85%29.aspx) یک کتابخونه کامل، برای بالا بردن کارآیی برنامه ها برای کار با سوکت ها بود، Microsoft® .NET یک لایه جدید روی Winsock بنام System.Net (http://msdn.microsoft.com/en-us/library/system.net.aspx) فراهم کرده که دیگه شما لازم نیست مستقیماً با Winsock کار کنید، درحقیقت همون کلاس System.Net.Sockets.Socket (http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.aspx) کل کارهای معمول در Winsock رو انجام میده. این لایه نیاز برنامه هایی که روی سوکت کار میکنند رو برای کدهای مدیریت شده دات نت فراهم میکنه؛ یعنی علاوه برمطمئن تر شدن زیرساخت های ارتباطی، خیلی امکانات جدید به لایه قبلی اش اضافه کرده که همین باعث گیج شدن کسایی میشه که فقط با Winsock کار کرده بودن (مثل من!)؛ ولی بتدریج متوجه میشین که تمام کارها و مشقاتی که در می کشیدیم بقول شما با دو تا کلاس TcpClient یا TcpListener حل شدن ولی بعضی ویژگی های پیشرفته که توسط کلاس سوکت های سطح پایین تر فراهم شده بود، دیگه تو اینها نیست و همین هم باعث کم شدن پیچیدگی شده؛ TcpListener (http://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.aspx) چند تا متد ساده برای listen و accept کردن connection های ورودی شما با توجه به روش synchronous (یعنی یا از Accept استفاده میکنین که ساده ترین حالت هست و درخواست های همزمان رو ژشتیبانی نمی کنه یا از BeginAccept که یک AsyncCallback میگیره مثلاً بعنوان OnAccept که کارهایی که قرار هست بعد Accept انجام بشه توش هست و ...) و مد Blocking فراهم میکنه و کلاس TcpClient (http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.aspx) متدهایی ساده برای connecting، sending و receiving استریم های داده روی شبکه (باز هم با توجه به نوع synchronous و blocking) داره؛ (برای UdpClient (http://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.aspx) قضیه فرق میکنه ولی چون مورد سوال شما نبود، بهش نپرداختیم) :


http://i.msdn.microsoft.com/cc300760.fig01%28en-us%29.gif


مثال های زیادی رو در تاپیک (تاپیک جامع چت (http://barnamenevis.org/showthread.php?346552-%D8%AA%D8%A7%D9%BE%DB%8C%DA%A9-%D8%AC%D8%A7%D9%85%D8%B9-%DA%86%D8%AA%21)) گذاشتم، که خودتون 100 تا بهترش رو می تونید گوگل کنید؛ برای ادامه قدم به قدم همین بحث هم من لینک پایین رو پیشنهاد میکنم:

Get Closer to the Wire with High-Performance Sockets in .NET (http://msdn.microsoft.com/en-us/magazine/cc300760.aspx#edupdate)


====================
برای فهمیدن این که کلاینت شما (یه Socket) کی connect شده هم در TcpClient (http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.aspx) یه Connected (http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.connected.aspx) هست که باید به اون نگاه کنید! اگه ارسال درخواست های همزمان داشته باشید (که اکثراً هم همینطور هست) باید یه AsyncCallback (http://msdn.microsoft.com/en-us/library/system.asynccallback.aspx) داشته یاشید (یک Delegate (http://msdn.microsoft.com/en-us/library/system.delegate.aspx) خاص برای عملیات همزمانی هست) که Connected توی اون چک میشه و اون رو به BeginReceive (http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.beginreceive.aspx) کلاینت میدین (Socket ای که برای کلاینت درست کردین)؛ ولی در حالت ساده فقط گذاشتن یک trace برای Connected (http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.connected.aspx) کافیه ...
#An Introduction to Socket Programming in .NET using C (http://www.codeproject.com/Articles/10649/An-Introduction-to-Socket-Programming-in-NET-using)

Direlap
چهارشنبه 31 خرداد 1391, 14:54 عصر
حالا فرق آسنکرون با سنکرون چیه ؟ میشه یه اشاره ای بکنید ؟

Saeed_m_Farid
چهارشنبه 31 خرداد 1391, 18:04 عصر
حالا فرق آسنکرون با سنکرون چیه ؟ میشه یه اشاره ای بکنید ؟
اگه تو مفهوم این دوتا اشکال دارین که خیلی ساده میشه گفت به Concurrency یا تعداد درخواستهایی که در آنِ‌واحد در جریان هستند، مربوط میشه؛ ارسال و دریافت همزمان درخواست ها و نوع رسیدگی به اونها این دو روش مجزا رو بوجود میارن، تو پست قبلی ام یه اشاره ای کردم:

اگه ارسال درخواست های همزمان داشته باشید (که اکثراً هم همینطور هست) باید یه AsyncCallback (http://msdn.microsoft.com/en-us/library/system.asynccallback.aspx) داشته یاشید (یک Delegate (http://msdn.microsoft.com/en-us/library/system.delegate.aspx) خاص برای عملیات همزمانی هست) که Connected توی اون چک میشه و اون رو به BeginReceive (http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.beginreceive.aspx) کلاینت میدین (Socket ای که برای کلاینت درست کردین)؛ ولی در حالت ساده فقط گذاشتن یک trace برای Connected (http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.connected.aspx) کافیه ...فرق کدنویسی رو هم از MSDN میتونید ببینید:


Using a Synchronous Client Socket (http://msdn.microsoft.com/en-us/library/6xt5x5zw.aspx)
Using an Asynchronous Client Socket (http://msdn.microsoft.com/en-us/library/bbx2eya8.aspx)

hamidhws
پنج شنبه 01 تیر 1391, 14:41 عصر
از توضیحاتتون ممنونم دوست عزیز
من کار با winsock رو خوب بلدم , به نظر شما لزومی داره از کلاس دات نت استفاده کنم؟ اگر بخوایم قدرت این 2 رو با هم مقایسه کنیم کدومشون قابلیت های بیشتری داره؟آیا تمام کارهایی که با کلاس دات نت میشه انجام داد با winsock هم شدنیست؟

ممنون میشم راهنمایی کنید.

سوال آخر (آیا جدیدترین نسخه winsock برای دات نت همون کتابخانه winsock2005 (http://barnamenevis.org/attachment.php?attachmentid=45922&d=1269367680) هست؟یا نسخه جدیدتر اومده؟)

Saeed_m_Farid
پنج شنبه 01 تیر 1391, 16:10 عصر
آقا جون، میتونم بپرسم چرا گیر دادی به Winsock ؟!
Winsock تو ++C/C بود (منظورم Native ها)؛ باور نمیکنی! ایناهاش (http://msdn.microsoft.com/en-us/library/windows/desktop/ms740673(v=vs.85).aspx) :


Developer audience
Windows Sockets 2 is designed for use by C/C++‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ programmers. Familiarity with Windows networking is required
تاپیک هم مال شصتاد سال پیش هم نیست، یکی دو هفته پیش بازبینی شده: Build date: 6/6/2012

من هم با Winsock2 کار میکردم، ولی تو دات نت الان این لایه (System.Net.Sockets.Socket (http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.aspx)) اومده روش و کلی هم امکانات اضافه شده بهش؛ تو مثال های لینکی که بالا دادم، ببنبید یه مثال #C یا VB.NET (یا هر کد مدیریت شده دیگه ای) هست؟(مثلاً (http://msdn.microsoft.com/en-us/library/windows/desktop/bb530741(v=vs.85).aspx))
کار کردن با System.Net هم خیلی راحته؛ ضمناً تمام کارها که با اون میشد، با این هم میشه و بیشترش هم میشه! ولی قبول کنید که باید یکمی بیخیال چیزایی که قبلاً استفاده میکردین بشین! اصلاً دات نت کارها رو راحت و امکان اشتباهات سهوی رو کم میکنه:

http://www.winsocketdotnetworkprogramming.com/systemdotnetsocketwinsocknetwork6_files/systemdotnetsocketwinsock002.png


http://www.winsocketdotnetworkprogramming.com/systemdotnetsocketwinsocknetwork6_files/systemdotnetsocketwinsock010.png

راحتی استفاده اش رو خودتون ببینید:
Tutorials on .NET Windows Network Programming With Working C#‎, VB .NET and C++‎/CLI .NET Code Examples (http://www.winsocketdotnetworkprogramming.com/)
فصل شش به بعد (Part II - Using the Network With Code Implementations)

پ.ن.: البته هیچ چی %100 نبست، ممکنه اساتید الان بیان حکم اعدام صادر کنن:لبخند: پس با این ترفند که " البته من تا اینجا میدونستم، بازم نظر اساتید چی باشه!" امنیت جانی خودم رو تضمین میکنم...

Saeed_m_Farid
شنبه 03 تیر 1391, 11:42 صبح
پیرو پ.خ. زیر (البته با اجازه خودشون) :

... چیزی که هنوز درست متوجه نشدم اینه که فرمودید واسه اینکه بفهمیم کلاینتمون به سرور وصل شده از connected استفاده کنیم , که یک مقدار bool برمیگردونه . یعنی من باید اینو توی تایمر بذارم و لحظه به لحظه چک کنم؟
ما توی event , winsock هایی داشتیم مثل connected یا disconnected,... که میتونستیم کدهامونو توش بریزیم تا زمان رخ دادن event اجرا بشه اما توی این کلاس دات نت من event ی ندیدم .میشه توضیح بدید این قسمت به چه صورته؟ ...
شما پرسیدین System.Net.Sockets.TcpClient مثل winsock همچین چیزی داره یا نه؟ ("چه زمانی کانکشن وصل میشه ؟") من هم گفتم بلی (connected) ولی اینکه این به چه درد شما میخوره، من که نمیدونم کدتون به چه صورت هست! (مثلاً‌ دوست دارین خودتون یه Event واسش بنویسین و چرخ رو از اول اختراع کنید!) تو راه حل عمومی معمولاً ازش استفاده نمیشه، از چی استفاده میشه؟ Again:
==============
چون معمولاً‌ بعیده حالت سنکرون (Synchronous) بدرد کسی بخوره و بیشتر تو P2P کاربرد داره و از طرف دیگه مفهوم پیچیده ای توش نیست، من حالت عمومی موردنیاز رو توضیح میدم (توضیح داده ام و خواهم داد!) تو حالت Asynchronous شما لازم نیست دنبال event بگردین؛ اگه یه نگاهی به مثال که دادم می‌نداختین، همونطورکه گفتم شما BeginConnect می‌کنید و اونجا بهش یک AsyncCallback پاس میدین، اون همه کارها رو میکنه! کدش :
public static void Connect(EndPoint remoteEP, Socket client) {
client.BeginConnect(remoteEP,
new AsyncCallback(ConnectCallback), client );

connectDone.WaitOne();
}
حالا delegate (همون AsyncCallback که بالا پاس دادین یعنی ConnectCallback) شما بطور اتوماتیک هروقت Remote device شما در دسترس باشه (بقول شما event های مثل connected یا disconnected,... رخ بدن)، فراخوانی میشه و شما میتونید "کدهاتونو توش بریزین تا زمان رخ دادن event اجرا بشن" بعدش هم می تونید مثلاً به Application بگین که کارم تموم شد، تو هم برو پی کارت! اینطوری مثلاً:
private static void ConnectCallback(IAsyncResult ar) {
try {
// Retrieve the socket from the state object.
Socket client = (Socket) ar.AsyncState;

// Complete the connection.
client.EndConnect(ar);

Console.WriteLine("Socket connected to {0}",
client.RemoteEndPoint.ToString());

// Signal that the connection has been made.
connectDone.Set();
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}

Send و Receive هم تقریباً‌ یه همچین روالی دارن و براحتی میتونید با تعریف یک AsyncCallback براشون تمام کارهایی رو که میخواین انجام بدین، این باعث میشه کارهای موردنظرتون در Delegate شما، بدون زحمت و دردسر اینکه کلاینت Connect هست یا ای‌وای وسط کار DC‌ شد و ... انجام بگیره.
برای توضیحات بیشتر، لینک که دادم (Using an Asynchronous Client Socket) رو بخونین.
موفق باشید.

hamidhws
شنبه 03 تیر 1391, 16:26 عصر
ضمن تشکر

من سورس کد توی این (http://msdn.microsoft.com/en-us/magazine/cc300760.aspx#edupdate) لینک دانلود کردم و اونو تست کردم و به درستی کار میکنه
اما در بخش سرور از 3 طریق میشه هاست شد :

88652

حالا میخواستم بدونم این 3 روش چه فرقی با هم میکنن ؟

hamidhws
یک شنبه 04 تیر 1391, 14:13 عصر
اگه کسی از دوستان فرقشونو میدونه بیزحمت یه توضیحی بده

Saeed_m_Farid
یک شنبه 04 تیر 1391, 20:35 عصر
حالا میخواستم بدونم این 3 روش چه فرقی با هم میکنن ؟
شما برداشت خودت چیه؟ خوندین اینا رو:
Threaded Server (http://msdn.microsoft.com/en-us/magazine/cc300760.aspx#S4)
Using Select for Multiplexed I/O (http://msdn.microsoft.com/en-us/magazine/cc300760.aspx#S5)
Asynchronous I/O (http://msdn.microsoft.com/en-us/magazine/cc300760.aspx#S6)
برای راهنمائی، تو این مقاله سعی شده مرحله به مرحله سرور رو بهینه کنه، یعنی تعداد Thread های درگیر رو کم کنه، کارآیی رو ببره، مدیریت Thread ها رو خودش بگیره دستش: (خودش = دات نت)، callback رو بهینه کنه که دیگه نیاز به استفاده از thread های worker هم نباشه، مانیتورینگ بذاره و ...
پس از بالا به پائین (هم Button های مثال، هم لینک ها) اینایی که شمردم، میره بالا! اگه به کدها دقت کنید، آخری (Asynchronous I/O (http://msdn.microsoft.com/en-us/magazine/cc300760.aspx#S6)) هم پیچیدگی کدها کمتر شده و هم کارآئی بالاتر هست و این همون روشی هست که داداشت اولش پیشنهاد کرد! :لبخند: (BeginAccept، BeginSend، BeginReceive و ...)
بازم همون لینک ها رو مطالعه کنین، اگه چیزی به ذهنتون رسید که متوجه نمی شید؛ مطرح کنید تا در موردش صحبت کنیم، ولی خدائیش باید بخونید و اگه بفهمم که همینطوری پست دادین، به آقا ناظم میگم...