# برنامه نویسی با محصولات مایکروسافت > برنامه نویسی مبتنی بر Microsoft .Net Framework > WCF , Web Services , .Net Remoting >  آموزش سوکت پروگرمینگ

## ar.shirazi

بخش اول : سوکت های همگام (سنکرون)

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

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

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

----------


## ar.shirazi

در مدل کلاینت - سرور ، مبادلات زیر بین کلاینت و سرور رخ میدهد 
1- سرور سوکتی را تعریف میکند
2 - سرور سوکت را به یک IP که همان IP خودش است و یک پورت Bind میکند یا اختصاص میدهد
3-سرور به پورت گوش میدهد
4- کلاینت سوکتی را تعریف میکند و IP و پورت سرور را به آن اختصاص میدهد
5- کلاینت درخواست اتصال یا کانکت شدن به سرور را میدهد
6-سرور درخواست کلاینت را دریافت و آن را می پذیرد

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

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



ابتدا برنامه سمت سرور را مینویسم .
 در این برنامه می بایست یک پورت را باز کرده و به آن گوش دهیم  و دریافتی را نمایش دهیم .

ابتدا می بایست فضای نامهای زیر را با استقاده از 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

متغیرها و متدهای 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

حال به مطلب اصلی خود بازگردیم :
یک شیء از کلاس سوکت به صورت سراسری و 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

سورس برنامه  سمت سرور




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

ادامه دارد . . . . .

----------


## ar.shirazi

خب ، ظاهرا توی این دو سالی که ما نبودیم این تاپیک خیلی گرد و خاک خورده! اگه دوستان مایل باشند از زیر گرد وخاک بکشیمش بیرون و کمی سر و سامونش بدیم!

----------


## manitack

چرا تاپیک به این خوبی استاپ خورد.؟؟

----------


## ghacem.sh

آره دوستان ممنون میشم ادامه بدید
چون منبع در این مورد خیلی کمه

----------


## Ghorbany_Ros

salam
khaste nabashid
ma ghorbany hastam .
va taze dar morede Soket Programing shoro kardam vali Manba peida nakatdam .
Please Very Help
merci

----------


## reza_program

سلام
ممنون
باز هم ادامه بدید

----------


## mohsen_zelzela00

استاد ممنون میشم دوباره شروع کنید

----------


## hojatpoorb

عالیه تو رو خدا ادامه بدین که واقعا محتاج شدمتا آخر ترم باید پروژه رو تحویل بدم
ممنونم

----------


## mostafa_shaeri_tj

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

----------


## mohsen_zelzela00

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


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

یا علی مدد

----------


## hojatpoorb

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

----------


## solaleh s

> بخش اول : سوکت های همگام (سنکرون)
> 
> نویسنده : علیرضا شیرازی
> 
> منبع : http://shirazionline.net/system/content/view/25/9/
> 
> پیش نیاز : آشنایی با مفاهیم شبکه ای مانند IP و Port و Socket و Send - Receive و Client و Server


 سلام - من تازه توي اين گروه آمدم  و مي خواهم با سوكت پروگرمينگ برنامه mail box نويسم اگه كمك كنيد بي نهايت سپاسگذارم.

----------


## mohsen_zelzela00

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


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

----------


## mehran5

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

----------


## baghishani

سلام

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

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

----------


## rkhtahoora

سلام 
من پروژه چت محلي دارم،اين برنامه سمت سرور خيلي خوبه اما نميدونم كجا بايد بنويسم آخه من سي شارپ كار نكردم خاهشا كمكم كنيد زمان زيادي ندارم . نياز به توضيحات پايه اي تر دارم

----------


## rkhtahoora

چرا كسي جوابگونيست من به اطلاعات بيشتري نياز دارم 
خواهشا كمك كنيد

----------


## MahmoudiNik

سلام 
یه آموزش پیدا کردم که امیدوارم به دردتون بخوره
http://ehsanavr.com/wp-content/plugi...rogramming.rar

----------


## m * h * d

سلام اگه می شه این بحث رو ادامه بدید
خواهش می کنم

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

----------


## sh1369

اگه راست می گین سوکت پروگرمینگ توی دلفی رو توضیح بدین
منظورم آموزش کامل Indy

----------


## kahroba_d

دو تا تابع وا سه دریافت و ارسال 
تابع ارسال :

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) { /* ... */ }

----------

