zoukankan      html  css  js  c++  java
  • 命名管道跨进程通信实例1(转)

    原文地址:http://www.cnblogs.com/yukaizhao/archive/2011/08/08/namedpipeserverstream-example.html

    本文介绍命名管道使用实例,文中例子是几个客户端都通过一台服务器获得新生成的int类型id。

    服务器端功能:当客户端请求一个新的id时,将现有id自增1,然后返回给客户端。

    服务器端实现:在程序启动时,启动n个线程,在每个线程中都声明一个NamedPipeServerStream的实例,并循环的WaitForConnection(),将新的id写入到命名管道中,然后断开连接。在程序退出时释放NamedPipeServerStream实例

    服务器端代码:

    class Program
    {
        //命名管道名字
        private const string PIPE_NAME = "testpipe";
        //定义线程数,也是NamedPipeServerStream的允许最多的实例数
        private const int MAX_THREAD_COUNT = 3;
    
        private static volatile int _runingThreadCount = 0;
        private static volatile int _newID = 0;
    
        private static NamedPipeServerStream[] _serverStreams;
    
        static void Main(string[] args)
        {
            _serverStreams = new NamedPipeServerStream[MAX_THREAD_COUNT];
            //在进程退出时,释放所有NamedPipeServerStream实例
            AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit);
            //启动线程
            StartServers();
            Console.Read();
        }
        /// <summary>
        /// 进程退出时释放命名管道
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void CurrentDomain_ProcessExit(object sender, EventArgs e)
        {
            if (_serverStreams != null)
            {
                foreach (NamedPipeServerStream item in _serverStreams)
                {
                    item.Dispose();
                }
            }
        }
        /// <summary>
        /// 启动线程
        /// </summary>
        private static void StartServers()
        {
            for (int i = 0; i < MAX_THREAD_COUNT; i++)
            {
                Thread thread = new Thread(new ThreadStart(StartNewIDServer));
                thread.Start();
            }
        }
        /// <summary>
        /// 启动一个NamedPipeServerStream实例
        /// </summary>
        private static void StartNewIDServer()
        {
            NamedPipeServerStream stream = null;
            Console.WriteLine("start server in thread:" + Thread.CurrentThread.ManagedThreadId);
    
            stream = _serverStreams[_runingThreadCount] = new NamedPipeServerStream(PIPE_NAME,
                PipeDirection.InOut,
                MAX_THREAD_COUNT,
                PipeTransmissionMode.Message,
                PipeOptions.None);
            while (true)
            {
                stream.WaitForConnection();
    
                int newID = ++_newID;
                byte[] bytes = BitConverter.GetBytes(newID);
                stream.Write(bytes,0,bytes.Length);
                stream.Flush();
                Console.WriteLine("threadNo:"+Thread.CurrentThread.ManagedThreadId+"
    ");
                stream.Disconnect();
            }
        }
    }

    客户端的功能是不断的发出获得新id的请求,并打印新id,在客户端可以配置服务端的服务器IP。

    客户端代码:

    class Program
    {
        private const string PIPE_NAME = "testpipe";
        static void Main(string[] args)
        {
            Console.WriteLine("请输入任何字符回车开始执行程序...");
            Console.Read();
            do
            {
                //内网服务器IP,必须是局域网
                string serverName = "127.0.0.1";
                //声明NamedPipeClientStream实例
                using (NamedPipeClientStream clientStream=new NamedPipeClientStream(
                    serverName,
                    PIPE_NAME
                    ))
                {
                    //连接服务器
                    clientStream.Connect(1000);
                    //设置为消息读取模式
                    clientStream.ReadMode = PipeTransmissionMode.Message;
                    do
                    {
                        byte[] bytes = new byte[4];
                        clientStream.Read(bytes,0,4);
                        int val = BitConverter.ToInt32(bytes,0);
                        Console.WriteLine("NewID=="+val+"
    ");
                    } while (!clientStream.IsMessageComplete);
                }
                Thread.Sleep(1);
            } while (true);
        }
    }

    在sql server中就使用了命名管道在局域网内挂进程通讯。

    在声明NamedPipeServerStream实例是可以指定其实例个数,如果实例数超过这个数,就会抛出“所有管道范例都在使用中”的IO异常。

    本例不可以在实际项目中使用。

    程序源码下载

  • 相关阅读:
    程序员必须知道的10大基础实用算法及其讲解
    6 Java Exceptions that Haunts a Newbie Java Developer(Java菜鸟6种常见的异常)
    在线学习Java免费资源推荐(来自:importnew)
    Oracle触发器
    Oracle性能分析工具介绍及使用
    开口大数据闭口高并发,你们都是怎么回答
    Http中Get/Post请求区别
    快速排序算法
    MAG EF查询增加指定索引功能
    WEB传参
  • 原文地址:https://www.cnblogs.com/tianma3798/p/5069843.html
Copyright © 2011-2022 走看看