PDA

View Full Version : آموزش سوکت پروگرمینگ



ar.shirazi
یک شنبه 20 اسفند 1385, 05:29 صبح
بخش اول : سوکت های همگام (سنکرون)

نویسنده : علیرضا شیرازی

منبع : http://shirazionline.net/system/content/view/25/9/

پیش نیاز : آشنایی با مفاهیم شبکه ای مانند IP و Port و Socket و Send - Receive و Client و Server

ar.shirazi
یک شنبه 20 اسفند 1385, 05:39 صبح
در مدل کلاینت - سرور ، مبادلات زیر بین کلاینت و سرور رخ میدهد
1- سرور سوکتی را تعریف میکند
2 - سرور سوکت را به یک IP که همان IP خودش است و یک پورت Bind میکند یا اختصاص میدهد
3-سرور به پورت گوش میدهد
4- کلاینت سوکتی را تعریف میکند و IP و پورت سرور را به آن اختصاص میدهد
5- کلاینت درخواست اتصال یا کانکت شدن به سرور را میدهد
6-سرور درخواست کلاینت را دریافت و آن را می پذیرد

7- کلاینت اطلاعاتی را ارسال می کند
8- سرور اطلاعات را می گیرد
9- سرور اطلاعات را ارسال میکند و کلاینت آن را میگیرد
10- سرور بسته میشود
11- کلانیت بسته میشود

شکل زیر این مراحل را نمایش می دهد :


http://www.codeproject.com/csharp/TCPIPChat/ClientServer.jpg
ابتدا برنامه سمت سرور را مینویسم .
در این برنامه می بایست یک پورت را باز کرده و به آن گوش دهیم و دریافتی را نمایش دهیم .

ابتدا می بایست فضای نامهای زیر را با استقاده از using به کامپایلر سی شارپ معرفی کنیم :
System
System.Net
System.Net.Socket
System.Text
این کار را به این صورت انجام می دهیم :




using System;
using System.Net;
using System.Net.Sockets;
using System.Text;





اکنون متغیری به نام را به صورت سراسری و static تعریف میکنیم (از آنجایی که متد Main یک متد static است کلیه متغیرها و توابع مورد استفاده در آن نیز باید static باشند.)

ar.shirazi
یک شنبه 20 اسفند 1385, 05:40 صبح
متغیرها و متدهای Static را میتوان اینگونه تعریف کرد :
متغیرها و توابعی هستند که در یک کلاس به طور مشترک بین کلیه اشیاء گرفته شده از آن کلاس وجود دارند نه اینکه به ازای هر شیء یک نمونه از آن ایجاد شود. دسترسی به این متغیرها از طریق نام کلاس ممکن خواهد بود.
در مثال زیر کلاسی به نام Circle تعریف کرده ایم که دارای یک متغیر عادی به نام r است . این متغیر شعاع دایره را نگه میدارد.
متغیر PI به صورت static تعریف شده است چرا که عدد پی به ازای کلیه اشیاء این کلاس ثابت است.
در کلاس MainClass از کلاس Circle یک شیء ساخته ایم و از آن استفاده کرده ایم





class Circle
{
public static float PI =3.14;
public int r;

public static void PrintIt(double dbl)
{
Console.WriteLine(dbl);
}
}

class MainClass
{
static void Main(string[] args)
{
Circle cl = new Circle();
Console.WriteLine("Please Enter The Circle R");
cl.r = Convert.ToInt32( Console.ReadLine());

Circle.PrintIt(Circle.PI * cl.r * cl.r);
}
}

ar.shirazi
یک شنبه 20 اسفند 1385, 05:41 صبح
حال به مطلب اصلی خود بازگردیم :
یک شیء از کلاس سوکت به صورت سراسری و static ایجاد می کنیم :





static Socket sktListener;




در متد Main این سوکت را new مینکیم تا به آن حافظه اختصاص داده شود :





static void Main()
{
sktListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);




AddressFamily.InterNetwork به معنای این است که از شبکه ای استفاده میکنیم که دارای IP نسخه 4 است.
SocketType.Stream برای سوکت هایی است که میخواهند به صورت Stream داده ها را تبادل کنند

ProtocolType.Tcp که نوع پروتکل ما را مشخص میکند.

اکنون می باید ِم آدرس IP و یک Port به سوکت مان اختصاص دهیم :





IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, 1800);
sktListener.Bind(ipLocal);




از آنجایی که این برنامه در سمت سرور اجرا میشود آدرس IP خاصی به آن نمیدهیم و پورت 1800 را باز میکنیم. کلاس IPEndPoint برای مشخص نمودن یک نود یا یک کامپیوتر در شبکه به کار میرود.

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

اکنون زمان گوش دادن به پورت است :






sktListener.Listen(100);




عدد 100 نشانه آن است که حداکثر 4 connection میتوانند در صف قرار گیرند .
اگر در این لحضه در command prompt دستور netstat –an را تایپ کنید میتوانید ببینید که پورت 1800 باز شده و در حال گوش دادن است.
حال میباید تقاضای کانکت شدن کلاینت را بپذیریم :





sktListener = sktListener.Accept();




حال برای گرفتن داده ها ، می بایست یک بافرتعریف نماییم .
نکته : در سوکت پروگرمینگ ، داده ها به صورت آرایه ای از بایت ها منتقل می شوند. برای ارسال رشته های یونیکد و .... بایست آنها را کد گذاری کنیم . برای کد گذاری و کد گشایی از کلاس System.Text و متدهای آن استفاده کنیم. مثلا دستور زیر رشته salam را با فرمت Ascii به آرایه ای از بایت ها تبدیل میکند





byte[] byt = Encoding.ASCII.GetBytes("salam");




و متد زیر آن را رمزگشایی میکند :





string str = Encoding.ASCII.GetString(byt);




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






byte[] buffer = new byte[500];
sktListener.Receive(buffer);
string Data = Encoding.ASCII.GetString(buffer);




حال میتوانیم داده ها را پردازش کنیم :





Console.WriteLine(Data);

ar.shirazi
یک شنبه 20 اسفند 1385, 05:43 صبح
سورس برنامه سمت سرور





using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

static Socket sktListener;

static void Main(string[] args)
{
sktListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, 1800);
sktListener.Bind(ipLocal);


sktListener.Listen(100);
Console.WriteLine("Waiting For The Client");

sktListener = sktListener.Accept();

byte[] buffer = new byte[500];

sktListener.Receive(buffer);

Console.WriteLine("--- Client Sent This Message : ");
Console.WriteLine(Encoding.ASCII.GetString(buffer) );
sktListener.close();
}

ar.shirazi
یک شنبه 20 اسفند 1385, 05:44 صبح
ادامه دارد . . . . .

ar.shirazi
دوشنبه 18 آذر 1387, 15:42 عصر
خب ، ظاهرا توی این دو سالی که ما نبودیم این تاپیک خیلی گرد و خاک خورده! اگه دوستان مایل باشند از زیر گرد وخاک بکشیمش بیرون و کمی سر و سامونش بدیم!

manitack
جمعه 13 دی 1387, 15:22 عصر
چرا تاپیک به این خوبی استاپ خورد.؟؟

ghacem.sh
دوشنبه 05 اسفند 1387, 20:06 عصر
آره دوستان ممنون میشم ادامه بدید
چون منبع در این مورد خیلی کمه

Ghorbany_Ros
چهارشنبه 28 اسفند 1387, 15:57 عصر
salam
khaste nabashid
ma ghorbany hastam .
va taze dar morede Soket Programing shoro kardam vali Manba peida nakatdam .
Please Very Help
merci

reza_program
شنبه 01 فروردین 1388, 16:37 عصر
سلام
ممنون
باز هم ادامه بدید

mohsen_zelzela00
جمعه 21 فروردین 1388, 14:53 عصر
استاد ممنون میشم دوباره شروع کنید

hojatpoorb
یک شنبه 19 مهر 1388, 17:54 عصر
عالیه تو رو خدا ادامه بدین که واقعا محتاج شدمتا آخر ترم باید پروژه رو تحویل بدم
ممنونم

mostafa_shaeri_tj
سه شنبه 21 مهر 1388, 02:29 صبح
اگه ایجاد کننده ی تاپیک اجازه بدن ، من میتونم مباحث رو ادامه بدم. البته اگه استقبال شه.
فکر میکنم یکی از دلایلی که این تاپیک استاپ شد عدم استقبال بود.

mohsen_zelzela00
سه شنبه 21 مهر 1388, 19:46 عصر
اگه ایجاد کننده ی تاپیک اجازه بدن ، من میتونم مباحث رو ادامه بدم. البته اگه استقبال شه.
فکر میکنم یکی از دلایلی که این تاپیک استاپ شد عدم استقبال بود.

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

یا علی مدد

hojatpoorb
چهارشنبه 29 مهر 1388, 23:59 عصر
سلام خسته نباشید مطالبتون جالب بود اگه میشه ادامه بدید حتما کسانی که علاقه مند هستند سر میزنند

solaleh s
پنج شنبه 30 مهر 1388, 19:51 عصر
بخش اول : سوکت های همگام (سنکرون)

نویسنده : علیرضا شیرازی

منبع : http://shirazionline.net/system/content/view/25/9/

پیش نیاز : آشنایی با مفاهیم شبکه ای مانند IP و Port و Socket و Send - Receive و Client و Server
سلام - من تازه توي اين گروه آمدم و مي خواهم با سوكت پروگرمينگ برنامه mail box نويسم اگه كمك كنيد بي نهايت سپاسگذارم.

mohsen_zelzela00
شنبه 02 آبان 1388, 20:18 عصر
اگه ایجاد کننده ی تاپیک اجازه بدن ، من میتونم مباحث رو ادامه بدم. البته اگه استقبال شه.
فکر میکنم یکی از دلایلی که این تاپیک استاپ شد عدم استقبال بود.

دوست عزیز ما همچنان منتظر هستیم

mehran5
یک شنبه 01 آذر 1388, 13:14 عصر
باتشکر ازآقای شیرازی
مطالب تاپیک اینقدر خواننده رو محو می کنند که از تشکر و اظهار نظر یادشون میره .
اگه امکانش هست ادامه بدید.

baghishani
دوشنبه 05 بهمن 1388, 06:15 صبح
سلام

اگر کسی سوکت بلده بیاد و بنویسه

والله ثواب داره

rkhtahoora
دوشنبه 11 مرداد 1389, 11:06 صبح
سلام
من پروژه چت محلي دارم،اين برنامه سمت سرور خيلي خوبه اما نميدونم كجا بايد بنويسم آخه من سي شارپ كار نكردم خاهشا كمكم كنيد زمان زيادي ندارم . نياز به توضيحات پايه اي تر دارم

rkhtahoora
دوشنبه 11 مرداد 1389, 13:36 عصر
چرا كسي جوابگونيست من به اطلاعات بيشتري نياز دارم
خواهشا كمك كنيد

MahmoudiNik
یک شنبه 21 شهریور 1389, 00:13 صبح
سلام
یه آموزش پیدا کردم که امیدوارم به دردتون بخوره
http://ehsanavr.com/wp-content/plugins/download-monitor/download.php?id=SocketProgramming.rar

m * h * d
دوشنبه 08 آذر 1389, 15:54 عصر
سلام اگه می شه این بحث رو ادامه بدید
خواهش می کنم

با تشکر از همه اساتید

sh1369
جمعه 03 دی 1389, 23:33 عصر
اگه راست می گین سوکت پروگرمینگ توی دلفی رو توضیح بدین
منظورم آموزش کامل Indy

kahroba_d
یک شنبه 05 شهریور 1391, 13:21 عصر
دو تا تابع وا سه دریافت و ارسال
تابع ارسال :

public static void Send(Socket socket, byte[] buffer, int offset, int size, int timeout) { int startTickCount = Environment.TickCount; int sent = 0; // how many bytes is already sent do { if (Environment.TickCount > startTickCount + timeout) throw new Exception("Timeout."); try { sent += socket.Send(buffer, offset + sent, size - sent, SocketFlags.None); } catch (SocketException ex) { if (ex.SocketErrorCode == SocketError.WouldBlock || ex.SocketErrorCode == SocketError.IOPending || ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable) { // socket buffer is probably full, wait and try again Thread.Sleep(30); } else throw ex; // any serious error occurr } } while (sent < size); }]

استفاده :
Socket socket = tcpClient.Client; string str = "Hello world!"; try { // sends the text with timeout 10s
Send(socket, Encoding.UTF8.GetBytes(str), 0, str.Length, 10000); } catch (Exception ex) { /* ... */ } ]

تابع دریافت :

public static void Receive(Socket socket, byte[] buffer, int offset, int size, int timeout) { int startTickCount = Environment.TickCount; int received = 0; // how many bytes is already received do { if (Environment.TickCount > startTickCount + timeout) throw new Exception("Timeout."); try { received += socket.Receive(buffer, offset + received, size - received, SocketFlags.None); } catch (SocketException ex) { if (ex.SocketErrorCode == SocketError.WouldBlock || ex.SocketErrorCode == SocketError.IOPending || ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable) { // socket buffer is probably empty, wait and try again Thread.Sleep(30); } else throw ex; // any serious error occurr } } while (received < size); }]

نحوه استفاده :

Socket socket = tcpClient.Client; byte[] buffer = new byte[12]; // length of the text "Hello world!" try { // receive data with timeout 10s
Receive(socket, buffer, 0, buffer.Length, 10000); string str = Encoding.UTF8.GetString(buffer, 0, buffer.Length); } catch (Exception ex) { /* ... */ }