C#进程间通信的几种方式:管道通信

年底了,有了大把时间,终于着手尝试写写技术博客,跟大家交流下心得。

就从进程间通信相关的内容开始吧,在此对以往工作中用到的几种进程间通信方式做一下简单的总结。

进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。进程间通信的方式(C/S结构开发环境)通常有管道、Socket、消息队列、信号量、共享存储、Streams等。

方式一:管道通信

管道通信(Communication Pipeline)即发送进程以字符流形式将大量数据送入管道,接收进程可从管道接收数据,二者利用管道进行通信。根据管道的使用范围划分为无名管道和命名管道。作为C/S结构开发环境,主要通过命名管道来实现进程间的通信。

命名管道服务器端和客户端代码实现 NamePipe.cs

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

namespace ForExample
{
    public class NamedPipe
    {
        #region 成员变量
        /// <summary>
        /// 发送消息
        /// </summary>
        private string _sendData;

        /// <summary>
        /// 发送端口名称
        /// </summary>
        private string _sendPort;

        /// <summary>
        /// 接受端口名称
        /// </summary>
        private string _receivePort;

        /// <summary>
        /// 接受数据回调函数
        /// </summary>
        private event ResultCallBackPoint _resultCallBackEvent;

        /// <summary>
        /// 客户端线程
        /// </summary>
        private Thread pipeCliendThread;

        /// <summary>
        /// 服务器端线程
        /// </summary>
        private Thread pipeServerThread;

        /// <summary>
        /// 客户端管道
        /// </summary>
        private NamedPipeClientStream namedPipeClientStream;

        /// <summary>
        /// 服务器端管道
        /// </summary>
        private NamedPipeServerStream namedPipeServerStream;

        #endregion

        /// <summary>
        /// 交互类 结构函数
        /// </summary>
        /// <param name="sendPort">发送端口名称</param>
        /// <param name="receivePort">接受端口名称</param>
        public NamedPipe(string sendPort, string receivePort)
        {
            _sendPort = sendPort;
            _receivePort = receivePort;
        }

        #region 客户端发送

        /// <summary>
        /// 发送
        /// </summary>
        public void Send(string sendData)
        {
            _sendData = sendData;
            pipeCliendThread = new Thread(new ThreadStart(PipeClient));
            pipeCliendThread.IsBackground = true;
            pipeCliendThread.Start();
        }

        /// <summary>
        /// 客户端
        /// </summary>
        private void PipeClient()
        {
            try
            {
                namedPipeClientStream = new NamedPipeClientStream(".", _sendPort, PipeDirection.InOut, PipeOptions.None);
                namedPipeClientStream.Connect(10000);
                StreamWriter sw = new StreamWriter(namedPipeClientStream);
                sw.WriteLine(_sendData);
                sw.Flush();
            }
            catch (Exception ex)
            {
                CallBackMsg(0, ex.ToString());
            }
        }

        #endregion

        #region 服务器端接受

        /// <summary>
        /// 接收端
        /// </summary>
        public void Receive()
        {
            pipeServerThread = new Thread(new ThreadStart(PipeServer));
            pipeServerThread.IsBackground = true;
            pipeServerThread.Start();
        }

        /// <summary>
        /// 服务器
        /// </summary>
        private void PipeServer()
        {
            try
            {
                namedPipeServerStream = new NamedPipeServerStream(_receivePort, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
                namedPipeServerStream.BeginWaitForConnection(CallBackReceiveData, namedPipeServerStream);
            }
            catch (Exception ex)
            {
                CallBackMsg(0, ex.ToString());
            }
        }

        /// <summary>
        /// 连接接受回调函数
        /// </summary>
        /// <param name="result"></param>
        private void CallBackReceiveData(IAsyncResult result)
        {
            try
            {
                NamedPipeServerStream pipeServer = (NamedPipeServerStream)result.AsyncState;
                pipeServer.EndWaitForConnection(result);

                StreamReader sw = new StreamReader(pipeServer);
                CallBackMsg(1, sw.ReadToEnd());

                namedPipeServerStream.Disconnect();
                namedPipeServerStream.BeginWaitForConnection(CallBackReceiveData, namedPipeServerStream);
            }
            catch (Exception ex)
            {
                CallBackMsg(0, ex.ToString());
            }
        }

        #endregion

        #region 委托

        /// <summary>
        /// 接受数据回调函数委托
        /// </summary>
        public delegate void ResultCallBackPoint(int code, string msg);

        #endregion

        /// <summary>
        /// 返回信息
        /// </summary>
        /// <param name="code">成功码</param>
        /// <param name="msg">信息</param>
        private void CallBackMsg(int code, string msg)
        {
            if (_resultCallBackEvent != null)
            {
                _resultCallBackEvent(code, msg);
            }

            pipeCliendThread = null;
            pipeServerThread = null;
        }
    }
}

该类封装了命名管道服务端和客户端创建连接、接收回调的相关方法,建立连接之后,客户端与服务器端即可通过ReadFile和WriteFile,利用得到的管道文件句柄,彼此间进行信息交换。

猜你喜欢

转载自blog.csdn.net/dnazhd/article/details/86535787
今日推荐