C#中进程间的通信:管道

    程序中有两个进程,并且一个进程需要和另一个进程进行通信,那么可以使用管道,所谓的C/S模式也和这个差不多。

    分为两端服务和客户端,下面简单说一下管道通信。两个类Server和Client,都包含如下方法:监听,接收,发送。

如下类:

Server类

    public class Server      {          [DllImport("kernel32.dll", SetLastError = true)]            public static extern SafeFileHandle CreateNamedPipe(               String pipeName,               uint dwOpenMode,               uint dwPipeMode,               uint nMaxInstances,               uint nOutBufferSize,               uint nInBufferSize,               uint nDefaultTimeOut,               IntPtr lpSecurityAttributes);            [DllImport("kernel32.dll", SetLastError = true)]            public static extern int ConnectNamedPipe(               SafeFileHandle hNamedPipe,               IntPtr lpOverlapped);            public const uint DUPLEX = (0x00000003);            public const uint FILE_FLAG_OVERLAPPED = (0x40000000);            public class Client          {              public SafeFileHandle handle;                public FileStream stream;          }            public delegate void MessageReceivedHandler(Client client, string message);            public event MessageReceivedHandler MessageReceived;            public const int BUFFER_SIZE = 4096;            string pipeName;            Thread listenThread;            bool running;            List<Client> clients;            public string PipeName          {              get { return this.pipeName; }                set { this.pipeName = value; }          }            public bool Running          {              get { return this.running; }          }            public Server()          {              this.clients = new List<Client>();          }            public void Start()          {              this.listenThread = new Thread(new ThreadStart(ListenForClients));                this.listenThread.Start();                this.running = true;          }            private void ListenForClients()          {              while (true)              {                  SafeFileHandle clientHandle =                    CreateNamedPipe(                         this.pipeName,                         DUPLEX | FILE_FLAG_OVERLAPPED,                         0,                         255,                         BUFFER_SIZE,                         BUFFER_SIZE,                         0,                         IntPtr.Zero);                    if (clientHandle.IsInvalid)                        return;                    int success = ConnectNamedPipe(clientHandle, IntPtr.Zero);                    if (success == 0)                        return;                    Client client = new Client();                    client.handle = clientHandle;                    lock (clients)                        this.clients.Add(client);                    Thread readThread = new Thread(new ParameterizedThreadStart(Read));                    readThread.Start(client);              }          }            private void Read(object clientObj)          {              Client client = (Client)clientObj;                client.stream = new FileStream(client.handle, FileAccess.ReadWrite, BUFFER_SIZE, true);                byte[] buffer = new byte[BUFFER_SIZE];                //ASCIIEncoding encoder = new ASCIIEncoding();                UTF8Encoding encoder = new UTF8Encoding();//可以传汉字                while (true)              {                  int bytesRead = 0;                    try                  {                      bytesRead = client.stream.Read(buffer, 0, BUFFER_SIZE);                  }                  catch                  {                      break;                  }                    if (bytesRead == 0)                        break;                      if (this.MessageReceived != null)                        this.MessageReceived(client, encoder.GetString(buffer, 0, bytesRead));              }              client.stream.Close();                client.handle.Close();                lock (this.clients)                    this.clients.Remove(client);          }            public void SendMessage(string message)          {              lock (this.clients)              {                  ASCIIEncoding encoder = new ASCIIEncoding();                    byte[] messageBuffer = encoder.GetBytes(message);                    foreach (Client client in this.clients)                  {                      client.stream.Write(messageBuffer, 0, messageBuffer.Length);                        client.stream.Flush();                  }              }          }      }

Client类

    public class Client      {          [DllImport("kernel32.dll", SetLastError = true)]            public static extern SafeFileHandle CreateFile(               String pipeName,               uint dwDesiredAccess,               uint dwShareMode,               IntPtr lpSecurityAttributes,               uint dwCreationDisposition,               uint dwFlagsAndAttributes,               IntPtr hTemplate);            public const uint GENERIC_READ = (0x80000000);            public const uint GENERIC_WRITE = (0x40000000);            public const uint OPEN_EXISTING = 3;            public const uint FILE_FLAG_OVERLAPPED = (0x40000000);            public delegate void MessageReceivedHandler(string message);            public event MessageReceivedHandler MessageReceived;            public const int BUFFER_SIZE = 4096;            string pipeName;            private FileStream stream;            private SafeFileHandle handle;            Thread readThread;            bool connected;            public bool Connected          {              get { return this.connected; }          }            public string PipeName          {              get { return this.pipeName; }                set { this.pipeName = value; }          }            public void Connect()          {              this.handle =                   CreateFile(                      this.pipeName,                      GENERIC_READ | GENERIC_WRITE,                      0,                      IntPtr.Zero,                      OPEN_EXISTING,                      FILE_FLAG_OVERLAPPED,                      IntPtr.Zero);                if (this.handle.IsInvalid)                    return;                this.connected = true;                this.stream = new FileStream(this.handle, FileAccess.ReadWrite, BUFFER_SIZE, true);                this.readThread = new Thread(new ThreadStart(Read));                this.readThread.Start();          }              public void Read()          {              byte[] readBuffer = new byte[BUFFER_SIZE];                ASCIIEncoding encoder = new ASCIIEncoding();                while (true)              {                  int bytesRead = 0;                    try                  {                      bytesRead = this.stream.Read(readBuffer, 0, BUFFER_SIZE);                  }                  catch                  {                      break;                  }                    if (bytesRead == 0)                      break;                    if (this.MessageReceived != null)                        this.MessageReceived(encoder.GetString(readBuffer, 0, bytesRead));              }              this.stream.Close();                this.handle.Close();          }            public void SendMessage(string message)          {              //ASCIIEncoding encoder = new ASCIIEncoding();                UTF8Encoding encoder = new UTF8Encoding();//可以传汉字                byte[] messageBuffer = encoder.GetBytes(message);                this.stream.Write(messageBuffer, 0, messageBuffer.Length);                this.stream.Flush();          }      }

Server端

    public class ServerPort      {          private Delegate sendMessage = null;            private ContainerControl mainForm;            public Server pipeServer = null;            public ServerPort(ContainerControl form,Delegate sendmessage)          {              mainForm = form;                sendMessage = sendmessage;          }            void SendMsg(string msg)          {              this.mainForm.Invoke(sendMessage, new Object[] { msg });          }            void PipeServer_MessageReceived(Server.Client client, string message)          {              if (!message.Equals(""))              {                  SendMsg("接收到的信息是:" + message);              }              else              {                  SendMsg("消息未收到???");              }          }            private void MessageSend()          {            }            public void PipServerStart()          {              try              {                  if (!this.pipeServer.Running)                  {                      this.pipeServer.PipeName = "\\\\.\\pipe\\testprocesspipe";                        this.pipeServer.Start();                        this.pipeServer.MessageReceived += new Server.MessageReceivedHandler(PipeServer_MessageReceived);                  }              }              catch              {              }          }      }

Client端,发送信息

    public class ClientPort      {          private static Client pipeClient;             public static void MessagePipeStart()          {              if (pipeClient == null)              {                  pipeClient = new Client();                    pipeClient.MessageReceived += new Client.MessageReceivedHandler(pipeClient_MessageReceived);              }                if (!pipeClient.Connected)              {                  pipeClient.PipeName = "\\\\.\\pipe\\testprocesspipe";                    pipeClient.Connect();              }                if (pipeClient != null && pipeClient.Connected)              {                  MessageSend("测试传输的字符:金胖子死了!!!");              }          }            static void MessageSend(string str)          {              pipeClient.SendMessage(str);          }            static void pipeClient_MessageReceived(string message)          {            }      }

启动服务端

            ServerPort serverPort;                recivedMessage += new ServerRecivedMessageDelegate(DisplayMessage);                try              {                  serverPort = new ServerPort(this, recivedMessage);                    serverPort.pipeServer = new Server();                    serverPort.PipServerStart();                }              catch              { }

客户端发送信息

            ClientPort.MessagePipeStart();

接收如图,

客户端发送后,服务端监听到,并接收

 

简单的例子下载地址:http://download.csdn.net/detail/yysyangyangyangshan/3946892

   上述 只是在一个工程中简单的模拟。正的进程的通信,Server端和Client端分别在两个进程中,启动的方式都一样,当两端都启动的话,就可以互发信息了。当然,PipeName必须一致,双方才能接收到对方的信息。

    这样,可以建造一个服务端,启动好几个Server设置PipeName 各不同,然后客户端分别对应不同的PipeName,就可实现服务器一对多的通信。

你可能感兴趣的:(thread,String,server,C#,buffer,encoding)