• C# IOCPServer 异步I/O模型


    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 IOCPServer : 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 IOCPServer()
    {
    onAccepted
    = new AsyncCallback(ListenEndAccept);
    onReceived
    = new AsyncCallback(ClientEndRecv);
    onSend
    = new AsyncCallback(ClientEndSend);
    }

    public IOCPServer(IntPtr handle)
    :
    this()
    {
    this.m_hWnd = handle;
    }

    public void Run()
    {
    new Thread(new ThreadStart(ListenThreadMethod)).Start();
    }

    /// <summary>
    ///
    /// </summary>
    private void ListenThreadMethod()
    {
    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(Packet 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(Packet msg)
    {
    //switch (msg.cmd)
    //{
    // case cmd.GetUserList:
    // break;
    // case cmd.Login:
    // Peer peer;
    // using (MemoryStream ms = new MemoryStream(msg.Content))
    // {
    // 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;
    //}
    }
    }
    }

      

  • 相关阅读:
    字符串转换整数 (atoi)
    Z 字形变换
    最长回文子串
    寻找两个有序数组的中位数
    二维码QRCode
    多个线程访问url
    store procedure 翻页
    store procedure example
    使用graphics2D给图片上画字符
    procedure的over(partition by ) function
  • 原文地址:https://www.cnblogs.com/LinFx/p/2123673.html
Copyright © 2020-2023  润新知