برنامه نویسیسی شارپ

آموزش برنامه نویسی سوکت در #C

مجله اینترنتی آی تی پورت

به بيان ساده مي توان گفت كه سوكت به تركيب یک آدرس ماشين ( IP ) و یک شماره درگاه ( Port ) گفته مي شود. اين دو با هم و بصورت مكمل هم در آدرس يابي تحت شبكه به برنامه هاي كاربردي كمك مي كنند كه هر برنامه تنها packet ارسالي خود را و تنها از آدرس مورد نظرش بدست آورد يا به عبارت ديگر علاوه به بحث رساندن بسته به كامپيوتر مقصد رساندن آن به برنامه كاربدي مربوطه نيز لازم است.

در مدل کلاینت – سرور ، مبادلات زیر بین کلاینت و سرور رخ می دهد:

  •  سرور سوکتی را تعریف میکند
  • سرور سوکت را به یک IP که همان IP خودش است و یک پورت Bind میکند یا اختصاص میدهد
  • سرور به پورت گوش میدهد
  • کلاینت سوکتی را تعریف میکند و IP و پورت سرور را به آن اختصاص میدهد
  • کلاینت درخواست اتصال یا کانکت شدن به سرور را میدهد
  • سرور درخواست کلاینت را دریافت و آن را می پذیرد
  • کلاینت اطلاعاتی را ارسال می کند
  • سرور اطلاعات را می گیرد
  • سرور اطلاعات را ارسال میکند و کلاینت آن را میگیرد
  • سرور بسته میشود 11- کلانیت بسته میشود

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

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

ابتدا مي بايست فضاي نامهاي زير را با استقاده از using  به کامپايلر سي شارپ معرفي کنيم:

using System;



using System.Net;



using System.Net.Sockets;



using System.Text;

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

 

 تعريف متغيرها و متدهاي Static

متغيرها و  توابعي هستند که در يک کلاس به طور مشترک بين کليه اشياء گرفته شده از آن کلاس وجود دارند  نه اينکه به ازاي هر شيء يک نمونه از آن ايجاد شود. دسترسي به اين متغيرها از طريق نام کلاس ممکن خواهد بود.

يک شيء از کلاس سوکت به صورت سراسري و static ايجاد مي کنيم :

staticSocket sktListener;

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

staticvoid Main()



{



sktListener = newSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);



 

AddressFamily.InterNetwork به معناي اين است که از شبکه اي استفاده مي کنيم که داراي IP نسخه 4 است.

SocketType.Stream براي سوکت هايي است که مي خواهند به صورت Stream  داده ها را تبادل کنند.

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

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

IPEndPoint ipLocal = newIPEndPoint(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 = newbyte[500];



sktListener.Receive(buffer);



string Data = Encoding.ASCII.GetString(buffer);

حال مي توانيم داده ها را پردازش کنيم.

 

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

using System;



using System.Net;



using System.Net.Sockets;



using System.Text;



 



staticSocket sktListener;



staticvoid Main(string[] args)



{



sktListener = newSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);



IPEndPoint ipLocal = newIPEndPoint(IPAddress.Any, 1800);



sktListener.Bind(ipLocal);



sktListener.Listen(100);



sktListener = sktListener.Accept();



byte[] buffer = newbyte[500];



sktListener.Receive(buffer);



sktListener.close();



}



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

 

برنامه سمت کلاينت

ايتدا يک سوکت تعريف مي کنيم.

Socket sktClient = newSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

حال سرور را به آن معرفي مي نماييم  و به آن کانکت مي شويم:

sktClient.Connect("127.0.0.1", 1800);

اگر دوباره دستور netstat –an را در Command prompt  تايپ کنيم مي بينيم که ارتباظ برقرار شده است. به شماره پورتها در آن دقت کنيد.

اکنون داده هاي ارسالي را آماده مي کنيم:

string str = "Hello Server....";



byte[] buffer = Encoding.ASCII.GetBytes(str);

داده ها را ارسال مي کنيم:

sktClient.Send(buffer);

و سوکت را ميبنديم :

sktClient.Close();

 

سورس کامل برنامه سمت کلاینت

using System;



using System.Net;



using System.Net.Sockets;



using System.Text;



 



staticvoid Main(string[] args)



{



Socket sktClient = newSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);



sktClient.Connect("127.0.0.1", 1800);



string str = "Hello Server....";



byte[] buffer = Encoding.ASCII.GetBytes(str);



sktClient.Send(buffer);



sktClient.Close();



}



 

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

سورس سرور:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.Net;

using System.Net.Sockets;





namespace Server1

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

        static Socket ServerSock;

        private void Form1_Load(object sender, EventArgs e)

        {

            ServerSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            IPEndPoint SockAdd = new IPEndPoint(IPAddress.Any, 1050);

            ServerSock.Bind(SockAdd);

            ServerSock.Listen(100);

            ServerSock = ServerSock.Accept();

        }



        private void button1_Click(object sender, EventArgs e)

        {

            try

            {

                NetworkStream Serverstream = new NetworkStream(ServerSock);

                byte[] buffer2 = new byte[100];

                ServerSock.Receive(buffer2);

                string Data = Encoding.ASCII.GetString(buffer2);

                listBox1.Items.Add("Maryam: "+Data);

                Serverstream.Flush();



            }

            catch (Exception ex)

            {

                MessageBox.Show(ex.ToString());

            }

        }



        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)

        {

            if (e.KeyChar == (char)Keys.Enter)

            {

                NetworkStream Serverstream = new NetworkStream(ServerSock);

                byte[] buffer3 = new byte[100];

                buffer3 = System.Text.Encoding.ASCII.GetBytes(textBox1.Text);

                ServerSock.Send(buffer3);

                Serverstream.Flush();

                listBox1.Items.Add("Me: " + textBox1.Text);

                textBox1.Clear();

            }

        }



    }

}





 

سورس کلاینت:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.Net;

using System.Net.Sockets;



namespace Client

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

        static Socket ClientSock;

        private void Form1_Load(object sender, EventArgs e)

        {

            ClientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            ClientSock.Connect("127.0.0.1", 1050);



        }



        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)

        {

            if (e.KeyChar == (char)Keys.Enter)

            {

                NetworkStream Clientstream = new NetworkStream(ClientSock);

                byte[] buffer1 = System.Text.Encoding.ASCII.GetBytes(textBox1.Text);

                ClientSock.Send(buffer1);

                Clientstream.Flush();

                listBox1.Items.Add("Me: "+ textBox1.Text);

                textBox1.Clear();

            }

        }



        private void button1_Click(object sender, EventArgs e)

        {

            byte [] buffer= new byte [100];

            NetworkStream Clientstream=new NetworkStream (ClientSock );

            ClientSock.Receive(buffer);

            string Data = Encoding.ASCII.GetString(buffer);

            listBox1.Items.Add("Server: "+ Data);

            Clientstream.Flush();



        }

    }

}

با تشکر از جناب سعید جعفری

گفتگوها
  1. دمتون گرم تحقیق دانشگاه رو راحت انجام دادم

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

  3. سرویس و نگهداری آسانسور

    سلام .دوره حضوریه م برای برنامه نویسی سوکت دارید آیا؟

  4. محمد آرمان

    سلام من میخوام برای یک بازی تحت شبکه موبایل که با وای فای انجام میگییره برنامه بنویسم آیا با این آموزشی که شما گذاشتین میتونم این کارو بکنم ؟

  5. سلام،ممنون از اموزشتون این برنامه را بدون خطا Trace کردم ولی در ادامه کار مشکل برخوردم :كه بعد از برقراري ارتباط client با سرور با توجه به بازه اي كه سرور قرار ميدهد عددي را وارد نماييد چنانكه اين عدد با عدد انتخابي سرور برابر بود پيغام win چنانچه كوچكتر بود small چنانچه بزرگتر بودbig اعلام شود و كاربر عدد ديگري وارد كند اين عمليات ١٠ بار انجام شود چنانچه كاربر نتوانست عدد انتخابي را وارد كند با you failed مواجهه شود و ارتباط قطع شود نكته. امكان اتصال چندين كلاينت بصورت همزمان فراهم شود و سرور براي هر كلاينت بازه متفاوتي را در نظر ميگيرد. ممنون

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

  6. مهشید

    ممنونم از آموزشتون

    اما من یکی با نحو اجرای این کدها مشکل دارم . واقعا ممنون می شم نحو اجرا هم توضیح بدید

  7. ﻣﺼﻂﻔﻲ

    ﻣﺘﺸﻜﺮ ﺑﺎﺑﺖ ﺁﻣﻮﺯﺵ

  8. Ali Eslami

    سلام خیلی ممنون بابت سایت خوبتون…

  9. sobhan mozfari

    با سلام و خسته نباشید

    من چند مدته زدم تو ار سوکت همه فیلم اموزشی هارو هم دیدم و کامل یاد گرفته ام و لی هنوز اون طوری ک خودم میخوام نیستم .منبع خیلی کمه و نتونسم منبعی پیدا کنم اگر کتاب چاپ شده چیزی سراغ دارید لطفا ان را بران ایمیل کنید ممنون

    سپاس

  10. الیزه

    ممنونم

  11. سلام

    من با Asp.net یک برنامه کلاینت سرور نوشتم که کاربر از طریق ای پی برای سرور دیتا ارسال میکنه . این برنامه در محیط کامپیوتر خودم و با ای پی استاتیک درست کار میکنه . اما وقتی برنامه رو روی این هاست که دارای ای پی اختصاصی است قرار میدم برنامه خطا میده .

    خطای سمت کلاینت : System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 212.83.185.60:9889

    at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)

    at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)

    می خواستم ببینم مشکل از تنظیمات هاسته یا از برنامه نویسی .

  12. ناشناس

    سلام

    من با Asp.net یک برنامه کلاینت سرور نوشتم که کاربر از طریق ای پی برای سرور دیتا ارسال میکنه . این برنامه در محیط کامپیوتر خودم و با ای پی استاتیک درست کار میکنه . اما وقتی برنامه رو روی هاست که دارای ای پی اختصاصی است قرار میدم برنامه خطا میده .

    خطای سمت کلاینت : System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 212.83.185.60:9889

    at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)

    at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)

    می خواستم ببینم مشکل از تنظیمات هاسته یا از برنامه نویسی .

    با تشکر

  13. محمدعلی

    سلام ببخشید

    من میخوام یه برنامه ساده آندروید بسازمم باید چه بخش هایی رو یاد بگیرم ؟

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

    خیلی سپاس گذارم

    1. پاسخ به محمدعلی
      حسین جاهدی

      سلام
      شما برای یادگیری برنامه نویسی اندروید بهتر هست از این سایت استفاده کنید.
      http://androidcode.ir
      در حال حاضر در آی تی پورت آموزش برنامه نویسی اندروید داده نشده
      موفق باشید.

  14. سلام تشکر بسیار عالی بود

    یک منبع دیگه پیدا کردم در این لینک برای دوستان قرار دادم

    http://s5.picofile.com/file/8153780042/Class4.rar.html

  15. جرثقیل سقفی

    بسیار عالی بود ممنون

  16. خیلی خوب بود، سپاس.

  17. واژه رمزنگاری صیح نمی باشد.

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

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

  19. فاطمه

    سلام خسته نباشید ممنون به خاطر اموزشتون من میخواستم بدونم چطور اون پیامی که از طرف کلاینت میاد تو سرور نمایش داده بشود

  20. عالییییییییییییییییی بود

شما چه فکر می‌کنید؟

تجربه یا پرسشتان را با ما در میان بگذارید. ایمیل شما منتشر نمی‌شود.

فقط متن ساده بنویسید؛ HTML پذیرفته نمی‌شود و نشانی‌ها به صورت لینک نمایش داده نمی‌شوند.

این سایت از اکیسمت برای کاهش جفنگ استفاده می‌کند. درباره چگونگی پردازش داده‌های دیدگاه خود بیشتر بدانید.