PDA

View Full Version : آموزش: آموزش استفاده از Pipe ها (ارسال و دریافت اطلاعات دو برنامه جدا از هم با لوله)



محسن شامحمدی
یک شنبه 03 مهر 1390, 13:02 عصر
توجه: این آموزش در دات نت 3.5 و بالاتر قابل اجراست.
با سلام خدمت دوستان
تا بحال شده نیاز داشته باشید که دو تا برنامه جدا از هم رو طوری بنویسید که به راحتی بتونن کلی اطلاعات بین هم دیگه رد و بدل کنن؟
بعضی از دوستان کار رو با استفاده از تابع SendMessage راه میندازن.
بعضی ها یک فایل متنی می ذارن و اطلاعات رو با اون جابجا می کنن.
بعضی ها از یک مسیر رجیستری استفاده می کنن.
و........
که هر کدوم در جای خودش معایبی داره.
ولی یک راه اصولی هست که اون هم استفاده از Pipe ها یا همون لوله هاست.
Pipe یک کانال ارتباطی بین دوتا برنامه ست که این دو برنامه می تونن به راحتی با هم اطلاعات رد و بدل کنن.
در زمان های گذشته استفاده از Pipe ها فقط کار افراد حرفه ای بود و استفاده از توابعی مثل:
CreateNamedPipe
ConnectNamedPipe
از فایل Kernel32.dll
ولی امروزه مایکروسافت این کار را بصورت کاملا ساده پیاده سازی کرده.
اکنون با یک مثال خیلی ساده این کار را پیاده سازی می کنیم و کاربرد آن را در عمل می بینیم:

ضمنا این مثال از سایت Msdn گرفته شده است:
کد سرور:

using System;
using System.IO;
using System.IO.Pipes;

class PipeServer
{
static void Main()
{
using (NamedPipeServerStream pipeServer =
new NamedPipeServerStream("testpipe", PipeDirection.Out))
{
Console.WriteLine("NamedPipeServerStream object created.");

// Wait for a client to connect
Console.Write("Waiting for client connection...");
pipeServer.WaitForConnection();

Console.WriteLine("Client connected.");
try
{
// Read user input and send that to the client process.
using (StreamWriter sw = new StreamWriter(pipeServer))
{
sw.AutoFlush = true;
Console.Write("Enter text: ");
sw.WriteLine(Console.ReadLine());
}
}
// Catch the IOException that is raised if the pipe is
// broken or disconnected.
catch (IOException e)
{
Console.WriteLine("ERROR: {0}", e.Message);
}
}
}
}


NamedPipeServerStream هم مثل بقیه Stream های دیگر دات نت از مدل همزمان و غیرهمزمان پشتیبانی می کند.
ضمنا این استریم full duplex است.یعنی در آن واحد می تواند هم اطلاعات را بخواند و هم بنویسد
نوشتن برنامه Client آن هم بسیار ساده است وفقط کافیست همین pipe را پیدا کنی و به آن متصل بشوی:

using System;
using System.IO;
using System.IO.Pipes;

class PipeClient
{
static void Main(string[] args)
{
using (NamedPipeClientStream pipeClient =
new NamedPipeClientStream(".", "testpipe", PipeDirection.In))
{

// Connect to the pipe or wait until the pipe is available.
Console.Write("Attempting to connect to pipe...");
pipeClient.Connect();

Console.WriteLine("Connected to pipe.");
Console.WriteLine("There are currently {0} pipe server instances open.",
pipeClient.NumberOfServerInstances);
using (StreamReader sr = new StreamReader(pipeClient))
{
// Display the read text to the console
string temp;
while ((temp = sr.ReadLine()) != null)
{
Console.WriteLine("Received from server: {0}", temp);
}
}
}
Console.Write("Press Enter to continue...");
Console.ReadLine();
}
}


پ.ن: کارکرد این روش تا حدودی شبیه به ارتباط Tcpserver و TCPClient است.با این تفاوت که این روش ساده تر است و نیز سرعت بهتری دارد.و همچنین برای این کار بهینه شده است.

jmfnima
سه شنبه 26 اردیبهشت 1391, 13:01 عصر
با سلام و تشکر از شما دوست عزیز
اگه میشه یک مثال شفاف تر وساده تر بیان کنید و اگه زحمتی نیست کدها رو هم یک توضیحی بدین . ممنون

PetekDincos
سه شنبه 26 اردیبهشت 1391, 14:56 عصر
با سلام
آیا امکان این وجود داره که در یه برنامه که با ++C نوشته شده یه سرور ایجاد کرد به این صورت و بعد از یه برنامه دیگه که با #C نوشته شده به عنوان کلاینت به آن وصل شد و مقدار نوشته شده را خواند با تشکر

mohammad bayervand
شنبه 11 شهریور 1391, 20:15 عصر
با سلام
آقای شامحمدی مطلب بسیار نغض و مفیدی را عنوان فرمودید:تشویق:
فقط لطف کنید برای ما شاگرد تنبالای ته کلاس یه توضیحی روی کدها ضمیمه بفرمایید.:خجالت:
ممنون:لبخند: