PDA

View Full Version : سوال: برنامه نویسی سوکت



mahdi bg
پنج شنبه 21 بهمن 1389, 18:10 عصر
سلام
اگر قرار باشه از طریق سوکت دوتا برتامه کلاینت و سرور بنویسم باید توع برنامه رو چی انتخاب کنم؟ application ، consol و یا ...
چطوری وقتی برنامه های رو نوشتم باید تستش کنم؟ (چطوری باید اجراشون کنم)

ممنون

Sirwan Afifi
پنج شنبه 21 بهمن 1389, 18:24 عصر
سلام دوست عزیز
اول هدف تو از نوشتن برنامه نویسی سوکت مشخص کن بعد می تونی خودت یکیشو انتخاب کنی.
به عنوان مثال میخوای برنامه بنویسی که توی شبکه سرچ کنه و پورت های باز رو یکی یکی لیست کنه این برنامه
دیگه نیاز به اینترفیسی خاصی نداره و میشه با همون کنسول نوشت.

Alexia Himmer
پنج شنبه 21 بهمن 1389, 22:26 عصر
عرض سلام خدمت شما دوست عزیز

اجازه بده اول یک مورد رو بررسی کنیم تا برسیم به سوال شما

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

socket programming در عمل به protocol های ارتباطی TCP/IP & UDP/IP وابسته است .

و زمانی که این مورد را مد نظر داریم 3 بخش اهمیت دارد :

1 - protocol
2 - آدرس IP
3 - شماره port

برای برنامه نویسی در این زمینه شما namespace , System.Net.Sockets رو وارد کنی و از دو کلاس TcpListener & TcpClient استفاده کنی.

TcpClient class یک سوکت برای دریافت و ارسال داده با استفاده از tcp پیاده سازی می کند.

Tcplistener هم متدهای ساده ای فراهم می کند که منتظر درخواست های اتصال ورودی مانده و به روش بلوک بندی سنکرون درخواست ها را می پذیرد.

در ادامه برات کد listening رو برای یک ارتباط ورودی رو قرار می دم .




namespace Listening
{
class Program
{
const int portno = 100;

static void Main(string[] args)
{

System.Net.IPAddress localadd = System.Net.IPAddress.Parse("127.0.0.1");

TcpListener lis = new TcpListener(localadd, portno);
lis.Start();

TcpClient tcpc = lis.AcceptTcpClient();

NetworkStream ns = tcpc.GetStream();
byte[] data = new byte[tcpc.ReceiveBufferSize];
int nbr=ns.Read (data ,0,System .Convert .ToInt32 (tcpc .ReceiveBufferSize );

Console .WriteLine ("Received: " + Encoding .ASCII .GetString (data ,0,nbr ));

Console .ReadLine ();


}
}
}


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

mahdi bg
جمعه 22 بهمن 1389, 06:29 صبح
سلام
با تشکر از ذوستان

سوال فرض کنید برنامه نوشته شده چطوری باید تستش کنم؟
(روی یک سیستم چطوری باید بین سرور و کلاینت پبام رد و بدل بشه)

Alexia Himmer
جمعه 22 بهمن 1389, 11:37 صبح
در مورد کدی که خدمتت تقدیم کردم منظورم این بود که Base کار رو متوجه بشی برای اساس گوش دادن به پورت . کدی که بالا مطرح شد یه چیز پایه ای و ساده ای هستش . برای تست کد بالا هم اون رو در حالا Console بنویس و اجرا کن . بعد CMD Prompt رو باز کن و دستور netstat -na رو اجرا کن . با توجه به port Number که در اولین خط کد برای Listening معرفی کردی می تونی روی ردیف IP , 127.0.0.1 و همون پورت ببینی که برنامه به حالت گوش دادن به پورت هستش و منتظر برای قبوی داده ورودی . دوباره پورت رو عوض کن و netstat -na رو اجرا کن و نتیجه رو مطمئن شو .

البته می تونی با استفاده از برنامه هایی مثل Netcat هم این موضوع رو تست کنی و ارتباط دو طرفه داشته باشی یا اینکه کد طرف مقابل رو خودت بنویسی

اگر لازم دیدی کد مقابلش رو هم خدمتت معرفی کنم , عنوان کن .

mahdi bg
جمعه 22 بهمن 1389, 12:48 عصر
سلام

من کد مقابلش رو هم توی کلاینت نوشتم
اما وقتی اجرا میکنم فقط یکبار پیام رد و بدل میشه و بعدش خطا میده (برنامه های کلاینت سرور رو با هم اجرا میکنم)
نمونه کدهای رو هم که دانلود کردم این مشکل رو داردن ، بعد از یک بار ارسال و دریافت پیام برنامه ها به خطا می خوره !!!!!!!

برای اینکه برنامه بارها بتونن پیام رد و بدل کنن باید چکار کنم؟!

Alexia Himmer
جمعه 22 بهمن 1389, 13:31 عصر
اگر مشکلی با باز بودن پورت نداری کد بالا را با اضافه کردن یه while به صورت زیر تغییر بده . اگه پورت قبول نمی شه firwall باید disable بشه.


namespace Listening
{
class Program
{
const int portno = 102;

static void Main(string[] args)
{

System.Net.IPAddress localadd = System.Net.IPAddress.Parse("127.0.0.1");

TcpListener lis = new TcpListener(localadd, portno);
lis.Start();
while (true)
{
TcpClient tcpc = lis.AcceptTcpClient();

NetworkStream ns = tcpc.GetStream();
byte[] data = new byte[tcpc.ReceiveBufferSize];
int nbr = ns.Read(data, 0, System.Convert.ToInt32(tcpc.ReceiveBufferSize));

Console.WriteLine("Received: " + Encoding.ASCII.GetString(data, 0, nbr));
}
Console .ReadLine ();


}
}
}

mahdi bg
شنبه 23 بهمن 1389, 06:00 صبح
سلام

یک سوال فرض کنید کلی کلاینت به برنامه وصل شدن ، چطوری باید اونا رو از هم تشخیص بدیم؟
وقتی در مرحله تست هستیم و کلاینت و سرور روی یک کامپیوتر هستن

ممنون

Alexia Himmer
شنبه 23 بهمن 1389, 19:31 عصر
عرض سلام

موردی رو که مطرح کردید کار ما رو یک گام به جلو می بره و کار کمی پیچیده تر میشه و مطمئنن طرح قبلی جوابگو نخواهد بود .

اینجا ما باید که کلاس جدید تعریف کنیم با این هدف که بتونیم اطلاعاتی در مورد client هایی که به server ما متصل می شوند رو داشته باشیم .

زمانی که client به server وصل می شود server یک نمونه از کلاس مورد نظر رو ایجاد می کنه و متغییر TcpClient رو به Constructor کلاس انتقال می ده .

و همین طور شما client IP رو گرفته و به عنوان index برای شناسایی client در hashtable وارد می کنید .

BeginRead() method عمل خواندن Async غیر همزمان از شی networkstream را در یک thread مجزا شروع می کند .

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

در ادامه کد نمونه موارد فوق رو خدمتت ارائه می دم . انشاا.. مورد استفاده قرار بگیره .

سوالی بود در خدمتت هستم .


class Clients
{

public static Hashtable allcls = new Hashtable();

private TcpClient _cl;
private string _clip;
private string _cln;
private byte[] data;
private bool rn = true;

public multiclients(TcpClient client)
{
_cl =client ;

_clip =client .Client .RemoteEndPoint .ToString ();
allcls .Add (_clip ,this );

data=new byte [_cl .ReceiveBufferSize ];
client .GetStream ().BeginRead (data,0,System .Convert .ToInt32 (_cl .ReceiveBufferSize ),ReciveMSG,null );
}