/* csc /t:library Share.cs */ namespace Microshaoft { using System; using System.Collections; using System.Collections.Generic; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using System.Runtime.Serialization.Formatters; public static class RemotingHelper { public static void StartRemoting ( Type RemotingType , string Url , int Port , WellKnownObjectMode ServiceMode ) { BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider(); provider.TypeFilterLevel = TypeFilterLevel.Full; IDictionary ht = new Hashtable(); ht["port"] = Port; TcpChannel tc = new TcpChannel(ht, null, provider); ChannelServices.RegisterChannel(tc, false); RemotingConfiguration.RegisterWellKnownServiceType(RemotingType, Url, ServiceMode); Console.WriteLine("Remoting Object Started ..."); } public static void StartRemoting<T> ( string Url , int Port , WellKnownObjectMode Mode ) { StartRemoting(typeof(T), Url, Port, Mode); } public static T GetRemotingLocalClientProxyObject<T> ( string Url ) { return (T) Activator.GetObject ( typeof(T) , Url ); } } } namespace Microshaoft.RemotingObjects.Share { using System; public interface IRemotingIoCP { void BeginSyncWaitFor(string command); void SendCommand(string command); } } /* csc /r:Share.dll Server.cs */ namespace Microshaoft { using System; using System.Threading; using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; using Microshaoft.Win32; public class IocpHandler<TSessionData, TIocpData> { public delegate void DataReceivedEventHandler ( IocpHandler<TSessionData, TIocpData> sender , TIocpData iocp ); public event DataReceivedEventHandler DataReceived; private bool _running = false; private SafeFileHandle _completionPort; public void CompleteHandle() { _running = false; _completionPort.Dispose(); } public void SendData(TIocpData data) { GCHandle gch = GCHandle.Alloc(data); unsafe { NativeMethods.PostQueuedCompletionStatus ( _completionPort , (uint) sizeof(IntPtr) , IntPtr.Zero , (IntPtr) gch ); } } private TSessionData _sessionData; public TSessionData SessionData { get { return _sessionData; } } public void BeginSyncWait(TSessionData session) { _sessionData = session; _completionPort = NativeMethods.CreateIoCompletionPort ( new IntPtr(-1) , IntPtr.Zero , IntPtr.Zero , 1 ); if(!_completionPort.IsInvalid) { _running = true; /// Thread thread = new Thread(Run); /// thread.Start(); Run(); } } private void Run() { while (_running) { uint r = 0; IntPtr PerHandleData; IntPtr lpOverlapped; NativeMethods.GetQueuedCompletionStatus ( _completionPort , out r , out PerHandleData , out lpOverlapped , 0xffffffff ); Console.WriteLine("GetQueuedCompletionStatus ... "); if(r > 0) { GCHandle gch = GCHandle.FromIntPtr(lpOverlapped); TIocpData data = (TIocpData) gch.Target; gch.Free(); if (DataReceived != null) { DataReceived(this, data); } } } } } } namespace Microshaoft.RemotingObjects.Server { using System; using System.Runtime.InteropServices; using Microshaoft; public class IocpProcessor { private IocpHandler<UserSessionData, IocpData> _iocpHandler; public IocpProcessor() { _iocpHandler = new IocpHandler<UserSessionData, IocpData>(); _iocpHandler.DataReceived += new IocpHandler<UserSessionData, IocpData>.DataReceivedEventHandler(_iocpHandler_DataReceived); } public void BeginSyncWaitFor(string command) { UserSessionData session = new UserSessionData(); session.CompleteCommand = command; _iocpHandler.BeginSyncWait(session); } public void SendData(IocpData data) { _iocpHandler.SendData(data); } void _iocpHandler_DataReceived(IocpHandler<UserSessionData , IocpData> sender, IocpData data) { if (sender.SessionData.CompleteCommand == data.Text) { sender.CompleteHandle(); } } } public class UserSessionData { public string UserName; public string CompleteCommand; } //[StructLayout(LayoutKind.Sequential)] public class IocpData { public string Text; } } namespace Microshaoft.RemotingObjects.Server { using System; using System.Threading; using System.Collections; using System.ServiceProcess; using System.ComponentModel; using System.Security.Principal; using System.Configuration.Install; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using Microshaoft; using Microshaoft.Win32; using Microshaoft.RemotingObjects; public class ServiceHost : ServiceBase { public static readonly string serviceName = "RemotingSyncIocpAsycInvokeService"; private static IocpProcessor _IocpProcessor; public static IocpProcessor IocpProcessor { get { return _IocpProcessor; } } static void Main(string[] args) { ServiceHost service = new ServiceHost(); int l = 0; bool needFreeConsole = false; if (args != null) { l = args.Length; } if (l > 0) { if (args[0].ToLower() == "/console") { needFreeConsole = true; NativeMethods.AllocConsole(); Console.Title = "Server ..."; Console.WriteLine("Alloc Console ..."); Console.WriteLine("Current User Identity: {0}", WindowsIdentity.GetCurrent().Name); Console.WriteLine(".Net Framework version: {0}", Environment.Version.ToString()); } Console.Title = "Server"; //不能以服务运行 Console.WriteLine("Console"); service.OnStart(null); Console.ReadLine(); return; } Console.WriteLine("Service"); ServiceBase.Run(service); if (needFreeConsole) { Console.WriteLine("Free Console ..."); NativeMethods.FreeConsole(); } } public ServiceHost() { CanPauseAndContinue = true; ServiceName = ServiceHost.serviceName; } protected override void OnStart(string[] args) { Console.WriteLine(Environment.Version.ToString()); _IocpProcessor = new IocpProcessor(); RemotingHelper.StartRemoting<RemotingIoCP> ( "iocp" , 8080 , WellKnownObjectMode.SingleCall ); Console.WriteLine("Server . , Press Enter key to exit."); } } [RunInstallerAttribute(true)] public class ProjectInstaller : Installer { private ServiceInstaller serviceInstaller; private ServiceProcessInstaller processInstaller; public ProjectInstaller() { processInstaller = new ServiceProcessInstaller(); serviceInstaller = new ServiceInstaller(); // Service will run under system account processInstaller.Account = ServiceAccount.LocalSystem; // Service will have Start Type of Manual serviceInstaller.StartType = ServiceStartMode.Manual; serviceInstaller.ServiceName = ServiceHost.serviceName; Installers.Add(serviceInstaller); Installers.Add(processInstaller); } } } namespace Microshaoft.Win32 { using System; using Microsoft.Win32.SafeHandles; using System.Runtime.InteropServices; public static class NativeMethods { [ DllImport ( "kernel32.dll" ) ] public static extern bool AllocConsole(); [ DllImport ( "kernel32.dll" ) ] public static extern bool FreeConsole(); [ DllImport ( "kernel32.dll" , CharSet = CharSet.Auto , SetLastError = true ) ] public static extern SafeFileHandle CreateIoCompletionPort ( IntPtr FileHandle , IntPtr ExistingCompletionPort , IntPtr CompletionKey , uint NumberOfConcurrentThreads ); [ DllImport ( "kernel32.dll" , CharSet = CharSet.Auto , SetLastError = true ) ] public static extern bool GetQueuedCompletionStatus ( SafeFileHandle CompletionPort , out uint lpNumberOfBytesTransferred , out IntPtr lpCompletionKey , out IntPtr lpOverlapped , uint dwMilliseconds ); [ DllImport ( "Kernel32" , CharSet = CharSet.Auto ) ] public static extern bool PostQueuedCompletionStatus ( SafeFileHandle CompletionPort , uint dwNumberOfBytesTransferred , IntPtr dwCompletionKey , IntPtr lpOverlapped ); } } namespace Microshaoft.RemotingObjects { using System; using Microshaoft; using Microshaoft.RemotingObjects.Share; using Microshaoft.RemotingObjects.Server; public class RemotingIoCP : MarshalByRefObject, IRemotingIoCP { public void BeginSyncWaitFor(string command) { ServiceHost.IocpProcessor.BeginSyncWaitFor(command); } public void SendCommand(string command) { IocpData data = new IocpData(); data.Text= command; ServiceHost.IocpProcessor.SendData(data); } } } /* csc /r:Share.dll Client.cs */ namespace ConsoleApplication { using System; using System.Threading; using Microshaoft; using Microshaoft.RemotingObjects.Share; public class Class1 { static void Main(string[] args) { Console.Title = "Client"; Class1 a = new Class1(); a.Run(); Console.WriteLine(Environment.Version.ToString()); Console.ReadLine(); } public void Run() { IRemotingIoCP _proxy = RemotingHelper.GetRemotingLocalClientProxyObject<IRemotingIoCP>("tcp://127.0.0.1:8080/iocp"); string s; while ((s = Console.ReadLine()) != "q") { Console.WriteLine("BeginSyncWaitFor: {0} at {1} blocking ...", s, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff")); _proxy.BeginSyncWaitFor(s); Console.WriteLine("EndSyncWaitFor: {0} at {1}", s, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff")); } } } } /* csc /r:Share.dll ControlerClient.cs */ namespace ConsoleApplication { using System; using System.Threading; using Microshaoft; using Microshaoft.RemotingObjects.Share; public class Class1 { static void Main(string[] args) { Console.Title = "Controler Client"; Class1 a = new Class1(); a.Run(); Console.WriteLine(Environment.Version.ToString()); Console.ReadLine(); } public void Run() { IRemotingIoCP _proxy = RemotingHelper.GetRemotingLocalClientProxyObject<IRemotingIoCP>("tcp://127.0.0.1:8080/iocp"); string s; while ((s = Console.ReadLine()) != "q") { _proxy.SendCommand(s); Console.WriteLine("SendCommand end: [{0}] at {1}", s, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff")); } } } }