.net 3.5的Socket异步完成端口
2010-06-28 12:18
309 查看
根据.net 3.5中的异步Socket完成的一个模块,用队列来处理tcp数据包的粘包问题,用事件将数据包通知给上层调用;
代码写的不是很好,发出来希望和大家共同交流学习。
因为是实际项目中用的模块,所以有些地方是按照项目需求做的,大体的结构还是没问题的,除了代码写的差点外!!!
一,主要类,进行异步Socket的基本处理,.net3.5中的Socket完成端口模型的实现
代码/************************************************************************/
/*此类设计的目的主要是为了处理半个数据包造成的丢包问题
/************************************************************************/
public class HaflBuffEventArgs:EventArgs
{
public HaflBuffEventArgs(byte[] buff)
{
_buff = buff;
}
private byte[] _buff;
public byte[] BUFF { get { return _buff; } }
}
public class halfbuff
{
public event EventHandler<HaflBuffEventArgs> HalfEvent;
public halfbuff(IPEndPoint iep)
{
client=iep;
pool = new Queue<byte[]>();
TimerCallback call = new TimerCallback(TimerCall);
mutex = new Mutex();
timer = new System.Threading.Timer(call, null, 0, 500);
}
public IPEndPoint client;
public Queue<byte[]> pool;
public System.Threading.Timer timer;
private System.Threading.Mutex mutex;
private string temphead = "", tempend = "", tempall = "";
private void TimerCall(object info)
{
mutex.WaitOne();
HaflBuffEventArgs e;
while (pool.Count > 0)
{
byte[] data = pool.Dequeue();
if (data.Length > 180) continue; //如果数据包长度大于 180 则丢弃
string strdata = Hex.byteToHexStr(data);
string[] sArry = Regex.Split(strdata, "11FF");
if (sArry[0] != "")
{
temphead = sArry[0];
tempall = tempend + temphead;
if (tempall.Substring(0, 4) == "11FF" && tempall.Substring(tempall.Length - 4, 4) == "EEFF")
{
e = new HaflBuffEventArgs(Hex.ConvertHexToBytes(tempall));
HalfEvent(null, e);
temphead = "";
tempend = "";
tempall = "";
}
}
if (sArry.Length > 1)
{
for (int i = 1; i < sArry.Length; i++)
{
if (sArry[i].Contains("EEFF"))
{
//一个完整的包
e = new HaflBuffEventArgs(Hex.ConvertHexToBytes("11FF" + sArry[i]));
HalfEvent(null, e);
}
else
{
if (i == sArry.Length - 1)
{
tempend = "11FF" + sArry[i];
}
}
}
}
}
mutex.ReleaseMutex();
}
}
public class halfbuffpool
{
private ArrayList arry;
public halfbuffpool()
{
arry = new ArrayList();
}
public void poolAdd(halfbuff e)
{
arry.Add(e);
}
public void poolDel(halfbuff e)
{
e.timer.Dispose();
arry.Remove(e);
}
public void poolClear()
{
arry.Clear();
}
public int Count { get { return arry.Count; } }
public halfbuff this[int index] { get { return (halfbuff)arry[index]; } }
public halfbuff GetClient(IPEndPoint iep)
{
foreach (halfbuff e in arry)
{
if(e.client==iep)
return e;
}
return null;
}
}
五,自定义的消息,事件,及其他,代码就不贴了,可下载项目文件查看
项目下载:/Files/cxwx/NetServers.rar
错误之处还请批评指正!
代码写的不是很好,发出来希望和大家共同交流学习。
因为是实际项目中用的模块,所以有些地方是按照项目需求做的,大体的结构还是没问题的,除了代码写的差点外!!!
一,主要类,进行异步Socket的基本处理,.net3.5中的Socket完成端口模型的实现
代码/************************************************************************/
/*此类设计的目的主要是为了处理半个数据包造成的丢包问题
/************************************************************************/
public class HaflBuffEventArgs:EventArgs
{
public HaflBuffEventArgs(byte[] buff)
{
_buff = buff;
}
private byte[] _buff;
public byte[] BUFF { get { return _buff; } }
}
public class halfbuff
{
public event EventHandler<HaflBuffEventArgs> HalfEvent;
public halfbuff(IPEndPoint iep)
{
client=iep;
pool = new Queue<byte[]>();
TimerCallback call = new TimerCallback(TimerCall);
mutex = new Mutex();
timer = new System.Threading.Timer(call, null, 0, 500);
}
public IPEndPoint client;
public Queue<byte[]> pool;
public System.Threading.Timer timer;
private System.Threading.Mutex mutex;
private string temphead = "", tempend = "", tempall = "";
private void TimerCall(object info)
{
mutex.WaitOne();
HaflBuffEventArgs e;
while (pool.Count > 0)
{
byte[] data = pool.Dequeue();
if (data.Length > 180) continue; //如果数据包长度大于 180 则丢弃
string strdata = Hex.byteToHexStr(data);
string[] sArry = Regex.Split(strdata, "11FF");
if (sArry[0] != "")
{
temphead = sArry[0];
tempall = tempend + temphead;
if (tempall.Substring(0, 4) == "11FF" && tempall.Substring(tempall.Length - 4, 4) == "EEFF")
{
e = new HaflBuffEventArgs(Hex.ConvertHexToBytes(tempall));
HalfEvent(null, e);
temphead = "";
tempend = "";
tempall = "";
}
}
if (sArry.Length > 1)
{
for (int i = 1; i < sArry.Length; i++)
{
if (sArry[i].Contains("EEFF"))
{
//一个完整的包
e = new HaflBuffEventArgs(Hex.ConvertHexToBytes("11FF" + sArry[i]));
HalfEvent(null, e);
}
else
{
if (i == sArry.Length - 1)
{
tempend = "11FF" + sArry[i];
}
}
}
}
}
mutex.ReleaseMutex();
}
}
public class halfbuffpool
{
private ArrayList arry;
public halfbuffpool()
{
arry = new ArrayList();
}
public void poolAdd(halfbuff e)
{
arry.Add(e);
}
public void poolDel(halfbuff e)
{
e.timer.Dispose();
arry.Remove(e);
}
public void poolClear()
{
arry.Clear();
}
public int Count { get { return arry.Count; } }
public halfbuff this[int index] { get { return (halfbuff)arry[index]; } }
public halfbuff GetClient(IPEndPoint iep)
{
foreach (halfbuff e in arry)
{
if(e.client==iep)
return e;
}
return null;
}
}
五,自定义的消息,事件,及其他,代码就不贴了,可下载项目文件查看
项目下载:/Files/cxwx/NetServers.rar
错误之处还请批评指正!
相关文章推荐
- .NET 3.5 异步 socket SocketAsyncEventArgs ---Clinet
- [置顶] 手把手教你玩转SOCKET模型:完成端口(Completion Port)详解
- 关于.NET中socket中的异步套接字的研究二
- Socket模型(二):完成端口(IOCP)
- 异步IO、APC、IO完成端口、线程池与高性能服务器之一 异步IO
- Windows系统编程之异步I/O和完成端口
- .net socket与完成端口、异步发送相关研究
- 一起谈.NET技术,.NET异步编程:IO完成端口与BeginRead
- DELPHI高性能大容量SOCKET并发:IOCP完成端口例子介绍
- 异步IO、APC、IO完成端口、线程池与高性能服务器之一 异步IO
- .net 中异步SOCKET发送数据时碰到的内存问题
- .NET Socket开发之异步Socket
- Flash使用xmlsocket与.net服务端异步通信
- .NET异步编程:IO完成端口与“.NET研究”BeginRead
- .net 3.5平台上的Socket开发
- 异步IO、APC、IO完成端口、线程池与高性能服务器之一 异步IO
- I/O异步之I/O完成端口
- 完成端口通讯服务器(IOCP Socket Server)设计(二)内存管理(AWE)
- 怎么利用完成端口监听多个不同端口的socket