Thursday, February 6, 2014

How to do Inter-Process Communication through Named Pipes?

Server.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

//Added
using System.IO.Pipes;
using System.IO;
using System.Threading;
using System.Security.Principal;
using server;
//using PipeServer;


namespace server
{
    /// <summary>
    /// PipeServer creates a listener thread and waits for messages from clients.
    /// Received messages are displayed in Textbox
    /// </summary>
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }



        private void Form1_Load(object sender, EventArgs e)
        {
            tbox.Text = "";
            Pipeserver.pipeName = "testpipe";
            Pipeserver.owner = this;
            //Pipeserver.ownerInvoker = new Invoker(this);
            ThreadStart pipeThread = new ThreadStart(Pipeserver.createPipeServer);
            Thread listenerThread = new Thread(pipeThread);
            listenerThread.SetApartmentState(ApartmentState.STA);
            listenerThread.IsBackground = true;
            listenerThread.Start();
        }

        public void setTextbox(string text)
        {
            if (tbox.InvokeRequired)
            {
                MethodInvoker invoker = () => setTextbox(text);
                tbox.Invoke(invoker);
            }
            else
            {
                tbox.Text = text;
            }
        }
    }




    public class Pipeserver
    {
        public static Form1 owner;
        //public static Invoker ownerInvoker;
        public static string pipeName;
        private static NamedPipeServerStream pipeServer;
        private static readonly int BufferSize = 256;

        //private static void SetTextbox(String text)
        //{
        //    owner.tbox.Text = String.Concat(owner.tbox.Text, text);
        //    if (owner.tbox.ExtentHeight > owner.tbox.ViewportHeight)
        //    {
        //        owner.tbox.ScrollToEnd();
        //    }
        //}

        public static void createPipeServer()
        {
            Decoder decoder = Encoding.Default.GetDecoder();
            Byte[] bytes = new Byte[BufferSize];
            char[] chars = new char[BufferSize];
            int numBytes = 0;
            StringBuilder msg = new StringBuilder();
            //ownerInvoker.sDel = SetTextbox;

            try
            {
                pipeServer = new NamedPipeServerStream(pipeName, PipeDirection.In, 1,
                                                PipeTransmissionMode.Message,
                                                PipeOptions.Asynchronous);
                while (true)
                {
                    pipeServer.WaitForConnection();

                    do
                    {
                        msg.Length = 0;
                        do
                        {
                            numBytes = pipeServer.Read(bytes, 0, BufferSize);
                            if (numBytes > 0)
                            {
                                int numChars = decoder.GetCharCount(bytes, 0, numBytes);
                                decoder.GetChars(bytes, 0, numBytes, chars, 0, false);
                                msg.Append(chars, 0, numChars);
                            }
                        } while (numBytes > 0 && !pipeServer.IsMessageComplete);
                        decoder.Reset();
                        if (numBytes > 0)
                        {
                            owner.setTextbox(msg.ToString());//ownerInvoker.Invoke(msg.ToString());
                        }
                    } while (numBytes != 0);
                    pipeServer.Disconnect();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
}




Client.cs:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.IO;
using System.IO.Pipes;
using System.Threading;
using System.Diagnostics;
using System.Security.Principal;

namespace Client
{
    public partial class Form1 : Form
    {
        public NamedPipeClientStream PipeStream;
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

              using (NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", "testpipe",
                                                          PipeDirection.Out,
                                                             PipeOptions.Asynchronous))
              {
                tbStatus.Text = "Attempting to connect to pipe...";
                try
                {
                  pipeClient.Connect(2000);
                }
                catch
                {
                  MessageBox.Show("The Pipe server must be started in order to send data to it.");
                  return;
                }
                tbStatus.Text = "Connected to pipe.";
                using (StreamWriter sw = new StreamWriter(pipeClient))
                {
                  sw.WriteLine(textBox1.Text);
                }
              }
              tbStatus.Text = "";

        }
    }
}


No comments:

Post a Comment