using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Net.Sockets; using System.Threading; using LinFx.Net; using LinFx.Win32; namespace LinFx.Net.Server { /// <summary> /// 异步I/O模型 /// </summary> public class CIOCPServer : IDisposable { private IntPtr m_hWnd; private Socket m_sListen; private System.Collections.ArrayList m_Clients = new System.Collections.ArrayList(); private readonly AsyncCallback onAccepted; private readonly AsyncCallback onReceived; private readonly AsyncCallback onSend; public CIOCPServer() { onAccepted = new AsyncCallback(ListenEndAccept); onReceived = new AsyncCallback(ClientEndRecv); onSend = new AsyncCallback(ClientEndSend); } public CIOCPServer(IntPtr handle) : this() { this.m_hWnd = handle; } public void Run() { ThreadPool.QueueUserWorkItem(new WaitCallback(ListenThreadMethod)); } /// <summary> /// /// </summary> private void ListenThreadMethod(object obj) { IPAddress ip = IPAddress.Parse("222.222.222.187"); IPEndPoint ipe = new IPEndPoint(ip, 1234); m_sListen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); m_sListen.Bind(ipe); m_sListen.Listen(50); //预先投递 Accept 请求 for (int i = 0; i < 5; i++) { PostAccept(); } } #region CallBack /// <summary> /// 请求 callback /// </summary> /// <param name="asyncResult"></param> private void ListenEndAccept(IAsyncResult asyncResult) { //投递一个 Accept 请求 PostAccept(); AsyncState state = asyncResult.AsyncState as AsyncState; Socket socket = state.socket.EndAccept(asyncResult); lock (this.m_Clients.SyncRoot) { this.m_Clients.Add(socket); } //投递一个接收请求 PostRecv(socket); } /// <summary> /// 接收 callback /// </summary> /// <param name="asyncResult"></param> private void ClientEndRecv(IAsyncResult asyncResult) { AsyncState state = asyncResult.AsyncState as AsyncState; int recvSize = state.socket.EndReceive(asyncResult); //远端连接已关闭 if (recvSize == 0) { lock (this.m_Clients.SyncRoot) { this.m_Clients.Remove(state.socket); } return; } //再投递一个接收请求 PostRecv(state.socket); //将收到的数据发送回去 PostSend(state.buffer, state.offset, state.size, state.socket); } /// <summary> /// 发送 callback /// </summary> /// <param name="asyncResult"></param> private void ClientEndSend(IAsyncResult asyncResult) { AsyncState state = asyncResult.AsyncState as AsyncState; byte[] buffer = state.buffer; int sentBytes = state.socket.EndSend(asyncResult); int remainBytes = state.size - sentBytes; if (remainBytes <= 0) return; System.Diagnostics.Debug.WriteLine(string.Format("Buffer length: {0} Remain bytes: {1} Sent bytes: {2}", buffer.Length, remainBytes, sentBytes)); PostSend(buffer, buffer.Length - remainBytes, remainBytes, state.socket); } #endregion #region 投递重叠 I/O /// <summary> /// 投递接受 I/O /// </summary> private void PostAccept() { m_sListen.BeginAccept(0, onAccepted, new AsyncState(m_sListen)); } /// <summary> /// 接收 I/O /// </summary> /// <param name="socket"></param> private void PostRecv(Socket socket) { byte[] buffer = new byte[1024]; socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, onReceived, new AsyncState(buffer, 0, buffer.Length, socket)); } /// <summary> /// 发送 I/O /// </summary> /// <param name="buffer"></param> /// <param name="offset"></param> /// <param name="size"></param> /// <param name="socket"></param> private void PostSend(byte[] buffer, int offset, int size, Socket socket) { socket.BeginSend(buffer, offset, size, SocketFlags.None, onSend, new AsyncState(buffer, offset, size, socket)); } #endregion internal class AsyncState { public readonly byte[] buffer; public readonly int offset; public readonly int size; public readonly Socket socket; public AsyncState(Socket socket) { this.socket = socket; } public AsyncState(byte[] buffer, int offset, int size, Socket socket) { this.buffer = buffer; this.offset = offset; this.size = size; this.socket = socket; } } public void SendMessage(Message msg) { } #region Event //private static readonly object EventRun = new object(); public event EventHandler Start; //{ // add { Events.AddHandler(EventMovePrevious, value); } // remove { Events.RemoveHandler(EventMovePrevious, value); } //} protected virtual void OnRun(EventArgs e) { //EventHandler handler = (EventHandler)base.Events[EventMoveNext]; //if (handler != null) //{ // handler(this, e); //} } #endregion public void Dispose() { } /// <summary> /// 处理封包 /// </summary> /// <param name="msg"></param> void DispatchMsg(Message msg) { switch (msg.cmd) { case cmd.Hello: break; case cmd.GetUserList: break; case cmd.Login: Peer peer; using (MemoryStream ms = new MemoryStream(msg.body)) { System.Runtime.Serialization.Formatters.Binary.BinaryFormatter binSerialer = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); peer = (Peer)binSerialer.Deserialize(ms); } //Win32API.SendMessage(m_hWnd, break; default: break; } } } }
C# 异步I/O模型
最新推荐文章于 2023-05-08 09:32:51 发布