年底了,有了大把时间,终于着手尝试写写技术博客,跟大家交流下心得。
就从进程间通信相关的内容开始吧,在此对以往工作中用到的几种进程间通信方式做一下简单的总结。
进程间通信(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,利用得到的管道文件句柄,彼此间进行信息交换。