SocketAsyncEventArgs 单机测试成功突破 6W (转)

http://blog.csdn.net/luyikk/article/details/5081133

 SocketAsyncEventArgs 单机测试成功突破 6W,59999 还是 100%连接上去的 所以估计最高性能可能达到10W以上

请看图吧  由于页宽不够 不能够全显示不过你可以另存为图片查看

 

实现原理:

          采用 SocketAsyncEventArgs 池 和内存池实现.

  代码:

    /// <summary>  
/// 启动
/// </summary>
public void Start()
{
if (isDisposed == true)
{
throw new ObjectDisposedException("ZYServer is Disposed");
}

sock
= new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress,
1);

IPEndPoint myEnd
= (String.IsNullOrEmpty(Host)) ? (new IPEndPoint(Dns.GetHostEntry(Dns.GetHostName()).AddressList[0], Port)) : (new IPEndPoint(IPAddress.Parse(Host), Port));

sock.Bind(myEnd);
sock.Listen(
20);
SendTimeout
= 1000;
ReceiveTimeout
= 1000;

BuffManagers
= new BufferManager(MaxConnectCout * MaxBufferSize, MaxBufferSize);
BuffManagers.Inint();

SocketAsynPool
= new SocketAsyncEventArgsPool(MaxConnectCout);

for (int i = 0; i < MaxConnectCout; i++)
{
SocketAsyncEventArgs socketasyn
= new SocketAsyncEventArgs();
socketasyn.Completed
+= new EventHandler<SocketAsyncEventArgs>(Asyn_Completed);
SocketAsynPool.Push(socketasyn);
}

Accept();
}



void Accept()
{
if (SocketAsynPool.Count > 0)
{
SocketAsyncEventArgs sockasyn
= SocketAsynPool.Pop();
if (!Sock.AcceptAsync(sockasyn))
{
BeginAccep(sockasyn);
}
}
else
{
LogOutEvent(
null, LogType.Error, "The MaxUserCout");
}
}

void BeginAccep(SocketAsyncEventArgs e)
{
try
{

if (e.SocketError == SocketError.Success)
{


if (this.Connetions != null)
if (!this.Connetions(e))
{

LogOutEvent(
null, LogType.Error, string.Format("The Socket Not Connect {0}", e.AcceptSocket.RemoteEndPoint));
e.AcceptSocket
= null;
SocketAsynPool.Push(e);

return;
}



if (BuffManagers.SetBuffer(e))
{
if (!e.AcceptSocket.ReceiveAsync(e))
{
BeginReceive(e);
}

}

}
else
{
e.AcceptSocket
= null;
SocketAsynPool.Push(e);
LogOutEvent(
null, LogType.Error, "Not Accep");
}
}
finally
{
Accept();
}

}




void BeginReceive(SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success&&e.BytesTransferred>0)
{
byte[] data = new byte[e.BytesTransferred];

Array.Copy(e.Buffer, e.Offset, data,
0, data.Length);

if (this.BinaryInput != null)
this.BinaryInput.BeginInvoke(data, e, RecevieCallBack, BinaryInput);

if (!e.AcceptSocket.ReceiveAsync(e))
{
BeginReceive(e);
}
}
else
{
string message=string.Format("User Disconnect :{0}", e.AcceptSocket.RemoteEndPoint.ToString());

LogOutEvent(
null, LogType.Error, message);

if (MessageInput != null)
{
MessageInput(message, e,
0);
}

e.AcceptSocket
= null;
BuffManagers.FreeBuffer(e);
SocketAsynPool.Push(e);
if (SocketAsynPool.Count == 1)
{
Accept();
}
}

}

void RecevieCallBack(IAsyncResult result)
{
this.BinaryInput.EndInvoke(result);

}

void Asyn_Completed(object sender, SocketAsyncEventArgs e)
{
switch (e.LastOperation)
{
case SocketAsyncOperation.Accept:
BeginAccep(e);
break;
case SocketAsyncOperation.Receive:
BeginReceive(e);
break;

}

}

不用问太多 我也不讲 太多 代码是如此的简单

值得说明的是  建议使用 SocketAsyncEventArgs 进行监听的 读取数据包. 因为 这2个地方的 SocketAsyncEventArgs 是同一个,并且内存和 SocketAsyncEventArgs 对象都好回收 好控制

如果使用 SocketAsyncEventArgs 发送数据包那么 SocketAsyncEventArgs 就不好控制了 所以使用传统的异步模式比较好. 而数据包传出使用 异步代理 进行传出以免堵塞 SocketAsyncEventArgs 线程.

MSND 的 SocketAsyncEventArgs 除了SocketAsyncEventArgsPOOL 和内存Manager 其他纯属扯淡.最好别效仿.

 源代码下载地址: http://download.csdn.net/source/2653920 

又问题可以联系我 luyi@5173.com

       

posted @ 2011-07-25 14:56  董雨  阅读(962)  评论(0编辑  收藏  举报