PDA

View Full Version : آموزش: Socket Programming



V0R73X
پنج شنبه 30 تیر 1390, 05:27 صبح
سلام دوستان.
دیدم تو فروم C# درباره سوکت ها بحث شده گفتم یه آموزش بزارم امیدوارم خوشتون بیاد (این دومیشه!)
خوب ببینید در یک جمله سوکت پروگرامینگ یعنی اینکه بیایم یک سری اطلاعات رو با یک سری شیء به نام سوکت از یک Device یه یک Device دیگه منتقل کنیم. حالا این Device هر چیزی میتونه باشه روبات یا کامپیوتر یا کنسول بازی!
تو این پروسه دو سیستم (یا همون Device) دخیلند: یکی سمتی که میفرسته (Client) و یکی هم سمتی که دریافت میکنه (server). خوب است بدانید که اینترنت هم خودش مجموعه بسیار عظیمی از سوکت های گوناگونه، و وقتی که شما مثلا وارد سایت برنامه نویس میشید به سورو حاوی این سایت یک درخواست میفرستید که این درخواست ها یه صورت یک سری بسته های اطلاعات رد و بدل میشند. پس شما میشید هون کلاینت! سرور حاوی سایت بعد از اینکه درخواست شما رو دریافت کرد اون رو پردازش میکنه و پاسخ مناسبی به شما میده مثلا صفحه ی اول سایت برنامه نویس!
خوب میبینید که هر طرف کار متفاوتی انجام میده پس Socket Programming سرور با کلاینت فرق داره که من در این آموزش هر دو را با سورس کد آموزش میدم. باور کنید کد رو که نگاه کنید همه چیز براتون واضح میشه مخصوصا اگر قبلا تو cmd با پینگ، پروتوکل ها و... سروکار داشتید. کسانی هم که با برنامه نویسی سریال آشنایی دارند هم سوکت پروگرامینگ رو بسیار آسون یاذ میگیرند.

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace Client_Socket
{
//FILE TRANSFER USING C#.NET SOCKET - CLIENT
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("That program can transfer small file. I've test up to 850kb file");
IPAddress[] ipAddress = Dns.GetHostAddresses("localhost");
IPEndPoint ipEnd = new IPEndPoint(ipAddress[0], 5656);
Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
clientSock.Connect(ipEnd);


byte[] clientData = new byte[1024 * 5000];
string receivedPath = "C:/";

int receivedBytesLen = clientSock.Receive(clientData);

int fileNameLen = BitConverter.ToInt32(clientData, 0);
string fileName = Encoding.ASCII.GetString(clientData, 4, fileNameLen);

Console.WriteLine("Client:{0} connected & File {1} started received.", clientSock.RemoteEndPoint, fileName);

BinaryWriter bWrite = new BinaryWriter(File.Open(receivedPath + fileName, FileMode.Append)); ;
bWrite.Write(clientData, 4 + fileNameLen, receivedBytesLen - 4 - fileNameLen);

Console.WriteLine("File: {0} received & saved at path: {1}", fileName, receivedPath);

bWrite.Close();
clientSock.Close();
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine("File Sending fail." + ex.Message);
}

}
}
}
خوب این برنامه نویسی سوکت سمت کلاینت هست. تو این برنامه سوکت کلاینت کارش اینه که وصل شه به سرور و ببینه آیا چیزی برای دریافت هست یا نه، و اگر بود دریافت کنه و به صورت مناسب نمایش بده.:چشمک:
کد همیشه واضحه و برای یک برنامه نویس C# توضیحی لارم نداره ولی من با این حال باید به چند نکته اشاره کنم:
1. سوکت ها دو نوع دارند: Packet Based OR Stream Based
2. دو خانواده دارند: Windows / Linux
3. دو پروتکل استفاده میکنند: TCP/IP OR UDP
اینها همون آرگومان های متد سازنده سوکت هستند. توصیه میشود مانند کد استفاده کنید :لبخند:
خوب دیگه بقیش واضحه سوکت با متد Connect وصل میشه، یا متد Receive دریافت میکنه و با Close هم بسته میشه! آسونه، مگه نه؟ اگر هنوز هم نمیفهمید پیشنهاد میکنم به کتابی که در آینده اتچ میکنم مراجعه کنید، (اگر به ادامه بحث علاقه مندید از دکمه تشکر استفاده کنید) وقتی از ماهیت سوکت ها سر در آوردید یه نگاه دوباره به این کد بندازید همه چیز روشن میشه!
خوب حالا سمت سرور:

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace beginSocketServer
{
//FILE TRANSFER USING C#.NET SOCKET - SERVER
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("That program can transfer small file. I've test up to 850kb file");
IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, 5656);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
sock.Bind(ipEnd);
sock.Listen(100);
//clientSock is the socket object of client, so we can use it now to transfer data to client
Socket clientSock = sock.Accept();


string fileName = "test.txt";// "Your File Name";
string filePath = @"C:\FT\";//Your File Path;
byte[] fileNameByte = Encoding.ASCII.GetBytes(fileName);

byte[] fileData = File.ReadAllBytes(filePath + fileName);
byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);

fileNameLen.CopyTo(clientData, 0);
fileNameByte.CopyTo(clientData, 4);
fileData.CopyTo(clientData, 4 + fileNameByte.Length);


clientSock.Send(clientData);
Console.WriteLine("File:{0} has been sent.", fileName);


clientSock.Close();
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine("File Receiving fail." + ex.Message);
}
}
}
}
خوب میبینید که موضوع یکم پیچیده تر شد ولی نگران نباشید اگه دقت کنید میبینید که فقط یک سوکت اضافه شده و 4 متد جدید، همین! که اونا رو هم اگه دوستان پیگیری کنند تو پست های آینده توضیح میدم.
خواهشا پست اضافه یا آف نگذارید اگر به ادامه این بحث علاقه مندید فقط از دکمه تشکر استفاده کنید

V0R73X
چهارشنبه 26 مرداد 1390, 09:44 صبح
خوب چقدر عالی فکر نمیکردم مطالب سوکت پروگرمینگ اینقدر کم طرفدار داشته باشه!! البته الان که فکر میکنم میبینم تعجب زیادی نداره! آخه مثلا سوکت پروگرمینگ به چه دردی میخوره؟؟ مثلا ما بیایم این سوکت رو طراحی کنیم که چی؟؟
خوب من اینو اول بحث باید میگفتم، عیب نداره حالا میگم:
سوکت ها اولین و پایه ای ترین یونیت های برنامه نویسی شبکه هستند، و منظورم از "شبکه" همه جور شبکه هست: Wifi,Internet,LAN و شبکه Cellular که موبایل ها ازش استفاده میکنند و حتی Xbee که احتمالا حتی اسمش هم به گوشتون نخورده. همین اینترنتی که هر روز استفاده میکنید نتیجه میلیون ها سوکت هست که درخواست های شما رو میگیرند و به سرور میرسونند و اونجا باز سوکت هایی هستند که درخواست شما رو پردازش میکنند و صفحه مورد نظرتون رو بهتون نشون میدند! و این سوکت ها برای اجرا شدن به هیچ نرم افزار یا کامپایلری ندارند (اینقدر بنیادی اند!)
ما ایرانیا روبات هایی که میسازیم همشون یا خطی رو تعقیب میکنن یا ماز حل میکنن یا فوتبالیستن یا برای یه جور مسابقه دیگه، هیچکس نمیاد یه بار همه چی رو از پایه یاد بگیره و روبات خاص خودشو بسازه، بدون توجه به مسابقات و...
هیچکس فکر نکرده که روباتی بسازه که بتوان به اینترنت وصل کرد...! اینکار شاید به نظر خیلی سخت بیاد ولی من اینکار رو 1 ماه پیش انجام دادم با سوکت پروگرمینگ و پورت سریال، که AVR ازش استفاده میکنه. نمیدونم شاید این تاپیک رو باید در بخش embedded devices programming میزاشتم. :متفکر: مهم نیست کپی میکنم...!
یا این حال میخوام این آموزش رو کامل کنم!! برای همین 3-4 نفر انگشت شمار که دنبال ریشه ی برنامه نویسی هستند، در اعماق کدها جایی که همه این آتیش ها ازون بلند میشه!! با این سوکت ها هرکاری میشه کرد، حتی، سوکت پروگرمینگ در مبحث هکینگ هم استفاده میشه :شیطان: ولی توسط هکر های بسیار ماهر، حتی من هم هنوز اینکارو نکردم فقط دربارش مقاله خوندم...
تو این پست یکم بیشتر درباره سوکت پروگرمینگ سمت سرور بحث میکنیم.
سرور چیه؟ یه چیزیه! کارش چیه؟ اینه که به 24/7 گوش میده به درخواست هایی که ممکنه توسط کلاینت ها با متد Send فرستاده بشن. (پس متد Send برای فرستادن اطلاعات توسط سوکت کلاینت استفاده میشه. تاکید میکنم این متد برای سوکت کلاینته نه سرور) و پروگرمینگ این سوکت معلوم میکنه که با این درخواست ها دقیقا باید چیکار کرد!
خوب برای راه اندازی این سوکت باید از متد Bind استفاده کنیم که یک آرگومان میگیره که همون ipEndPoint هست. این ipEndPoint خودش 2 تا آرگومان میگیره که یکیش یه آدرش IP اختیاری هست که توسط این شیء استفاده بشه، و یکی هم شماره درگاه یا همون پورت (port) مورد نظر هست، که این پورت برای رد و بدل اطلاعات استفاده میشه. پورت 5656 پورت مورد استفاده پروتکل tcp هست که اطلاعات رو رد و بدل میکنه و هسته تمام شبکه های کامپیوتریه! درباره اینکه این پروتوکل دقیقا چی هست... خوب این دیگه واسه خودش مبحثیه و کتابهای زیادی هم دربارش نوشتن، ولی خوب شما تا همینجا بدونید که اصلاعات ردوبدل میکنه همین! :لبخند:
درباره اصلاعات بیشتر درباره ipEndPoint هم به اینجا مراجعه کنید: http://msdn.microsoft.com/en-us/library/system.net.ipendpoint.aspx
خوب امیدوارم الان از کلیات سر در آورده باشید، اگر سوالی داشتید در همین تاپیک بیان کنید جواب خواهم داد.

V0R73X
چهارشنبه 26 مرداد 1390, 11:30 صبح
خوب من یا آموزش نمیزارم یا آموزشی که میزارم کامل و جامع میزارم!! حالا هم میخوام دیگه این آموزش رو کامل کنم!
متد هایی که توضیح ندادم Listen و Accept بودن، که خوب زیاد نیازی به توضیح ندارن: Listen متدیست برای شروع عمل لیسنینگ یا همون گوش دادن که یک آرگومان داره که این آرگومان ماکسیمم تعداد درخواست هایی که میتوانند در یک لحظه توسط سرور پذیرفته شوند رو معلوم میکنه، مثلا، 100 یعنی اینکه تا 100 درخواست رو میتوان در یک لحظه پذیرفت. این پارامتر رو بهش میگن backlog.
متد بعدی که خیلی هم مهم هست accept هست که برای ساختن یک سوکت جدید استفاده میشه. به زبان ساده، این متد یک connection میسازه بین یک سوکت کلاینت و سوکت سرور! در اینجا ما از این متد برای ساختن سوکت کلاینت استفاده کردیم.
حالا شاید این سوال براتون پیش بیاد: چیکار کنیم اگه سوکت کلاینتی که میخوایم بسازیم روی سرور نباشه؟ مثلا ما یه روبات داریم، یه سرور هم داریم که از هم جدا هستند میخوایم اطلاعاتی رو از روباته بفرستیم به سرور! چیکار کنیم؟ کاری نداره اصلا لازم نیست Accept استفاده بشه سوکت رو جداگونه برای روبات میسازیم بعد با متد Connect وصلش میکنیم به سرور!
خوب حالا ممکنه این سوال براتون پیش بیاد: حالا سرور رو هم زدیم و کلاینت هم رو زدیم و اصلاعات رو هم فرستادیم. این اصلاعات رو سرور چطوری باید پردازش بشه؟؟ جواب اینه که: اول با متد Receive دریافت میکنیم بعد هم هرکاری بخوایم باهاشون میکنیم!


IList fileData=new IList(Of ArraySegment(Of Byte));
if(socket.receive(fileData)){
foreach(arraySegment Data in fileData){
if(arraySegment.toString()=="Hello")
console.WiteLine("Hello! I got your message");
}
}

این فقط یک مثاله هر کاری میتونید با این داده ها بکنید مثلا من یک کامپیوتر دارم میزنم ویروس کشی رو شروع کنه، بعدش یه برنامه مینویسم که هرموقع کارش تموم شد، به موبایل من زنگ بزنه! (البته این خیلی پیشرفتست! مثلا به جاش ایمیل بزنه، اینیکی ممکنه و قصد دارم در آینده آموزش هم بدم! :قهقهه:)
خب دیگه فقط باید کلی تمرین کنید. برای تکمیل بحث، این ها هم چند تا نکته هست که در مبحث سوکت پروگرمینگ باید بهشون توجه کنید:
1. داده ها بطورت بیتی انتقال داده میشوند (سوکت ها از ابتدایی ترین و پایه ای ترین یونیت های برنامه نویسی هستند مثل یک سلول در بدن، بنابراین با اینک در نهایت شبکه بزرگ و قدرتمندی رو میسازند اما به تنهایی قابلیت های پیشرفته رو دارا نیستند!)
2. سوکت سرور بر خلاف سوکت کلاینت هیچگاه بسته نمیشه چون همواره باید به درخواست های کلاینت گوش بده، پس باید همیشه باشه و فقط یکبار ساخته میشه.
3. قبل از استفاده از listen باید حتما از Bind استفاده کنید وگرنه با socket.exception مواجه میشید (یک ارور بد! :گیج:)
4. مقدار backlog به سیستم عامل سرور بستگی داره و هر مقداری که شما بهش میدید لزوما قابل قبول نیست، یعنی اینکه اگر این مقدار از ظرفیت سیستم عامل بیشتر باشه سیستم عامل خودش ماکسیمم مقدار backlog رو در نظر میگیره...!
5. همیشه بعد از استفاده از سوکت ببندینش وگرنه حافظه بیخودی اشغال میکنه!
اوکی مبحث کامل شد! آخیش حالا میتونم یه نفس راحت بکشم! حالا به نظرم توی اینرنت بین برنامه نویسان ایرانی حداقل یک آموزش کامل سوکت پروگرمینگ وجود داره!!:لبخندساده: البته اینم بگم که C# بهترین اینتخاب برای برنامه نویسان سوکت نیست ولی با این حال چون زبان پر استفاده ای هست معمولا بیشتر استفاده میشه، و حداقل میتونم بگم که از C بهتره!! امیدوارم لذت برده باشید...

V0R73X
چهارشنبه 26 مرداد 1390, 11:36 صبح
خوب اینم کتابی که قولش رو توی پست اول داده بودم مطالبو براتون کمی باز میکنه و شامل اطلاعاتی درباره سوکت هاست! :چشمک: البته آموزش سوکت پروگرمینگ در C هم هست ولی پیشنهاد میکنم فقط اطلاعات کلی سوکت ها رو ازین کتاب یاد بگیرید، چون برنامه نویسی سوکت معمولا تو C جواب نمیده به دلایل مختلف...:ناراحت:
توی Media _. Fire آپ کردم امیدوارم ف_ ی . ل _ تر نباشه...
دانلود از اینجا (http://www.mediafire.com/?duyj8c10mj7ll9f)

morteza271
چهارشنبه 26 مرداد 1390, 18:48 عصر
سلام دوست عزیز.

بایت این آموزشتون واقعا ممنون.خیلی خوبه.

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

با تشکر فراوان

sorooshk
چهارشنبه 26 مرداد 1390, 20:11 عصر
با سلام و تشکر از آموزش شما

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

اگر هم لطف بفرمایید آموزش Socket Programming را توسط زبان C#.Net آموزش دهید که خیلی بهتر می شود.
من چند وقتی هست هم تو سایت های خارجی و هم سایت های ایرانی برنامه نویسی میگردم تا در مورد سوکت به نتیجه خوبی برسم. به نتایج زیادی رسیدم و خوب هم بودند ولی هر کسی به روشی که بلد بوده آموزش داده که البته طبیعی هست ولی میخواستم شما لطف بفرمایید و با زبانی نسبتا ساده و گام به گام آموزش را ادامه دهید. ضمنا اگر می توانید کتاب آموزش Socket Programming توسط زبان C#.Net را هم چه به صورت الکترونیکی و چه به صورت کاغذی معرفی نمایید متشکر می شوم.
من خواستم آموزش خصوصی این مبحث را ببینم که مدرس مورد نظر من گفت تمامی مباحث Socket را به صورت خصوصی در 40 ساعت آموزش میده که هزینش میشد 600 هزار تومان که خوب فعلا توانایی پرداخت این حق التدریس را ندارم. پس خواهش می کنم لطفا شما کمکمان نمایید.

mmd2009
پنج شنبه 27 مرداد 1390, 07:25 صبح
ضمنا اگر می توانید کتاب آموزش Socket Programming توسط زبان C#.Net را هم چه به صورت الکترونیکی و چه به صورت کاغذی معرفی نمایید متشکر می شوم.

با سلام

یک کتاب 90 صفحه ای ترجمه شده هست تو همین انجمن جستجو بکنید پیداش میکنید مطالب خیلی خوبی توضیح داده و برای کسانی که تازه میخوان شروع بکنن خیلی مفید هست

اگر اون کتاب رو خوندید بعدش مثال های زیادی هم زده شده تو این انجمن که باز میتونید استفاده کنید و یک مثال کامل در مورد Client/Server هم اقای یاراحمدی گذاشتن که پیشنهاد میکنم اون رو هم ببینید

موفق باشید.

monamor
شنبه 10 دی 1390, 02:09 صبح
با تشکر اگه امکانش هست پروتکل UDP رو هم بیان کنید. ممون

mohammadhosin
جمعه 23 تیر 1391, 11:16 صبح
سلام به همه دوستان
فکر کنم خیلی از آخرین پست گذشته
و با تشکر از دوستمون برای آموزش مفید

یه سوالای برام پیش اومده
چطوری ما میتونیم آدرس آی پی sender به صورت دستی تغییر بدیم در سوکت

bahmanbit
جمعه 13 اردیبهشت 1392, 19:50 عصر
خیلی عالی بود .
آموزش خیلی خوبی بود