• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C#IOCPServer异步I/O模型

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
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;
//}
}
}
}

  


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
GUID字符串,16位字符串,19位数字在C#中生成唯一的字符串和数字 ...发布时间:2022-07-13
下一篇:
在C#中使用CURL发布时间:2022-07-13
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap