/*
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"));
}
}
}
}