您的位置:首页 > 编程语言

一次.net Socket UDP编程的10万客户端测试记录

2010-12-15 14:15 288 查看
  最近想写一个网络服务器端的程序,想看看在大量客户端数下程序的运行情况。于是对.net 的Socket编程进行了一些研究,发现.net 3.5 里SocketAsyncEventArgs 是基于IOCP实现。MSDN上有相关的示例,但它是基于TCP协议的,而我想要的是基于UDP协议的。网上很难找到基于UDP协议的SocketAsyncEventArgs示例(UDP需要用IOCP吗?),于是决定自己写一个基于UDP协议的SocketAsyncEventArgs示例,看看它在和大量客户端通讯时的运行情况。

示例简介

  程序分为服务器端和客户端,它们使用UDP协议进行通讯。众所周知UDP是无连接的,可我又想计算出有多少客户端和服务器通信,其中又有多少是新的客户端。所以设计让服务器端程序绑定两个端口。一个端口专门用于接收客户端第一次发送过来的数据包;另一个端口负责和已经接入的客户端进行通讯(是不是有点像TCP的接入,例子本身也在模仿Tcp编程)。客户端比较简单让它生成足够多的Socket,然后不断的向服务器端发送数据包即可。

UDPReceiceSocket

  UdpReceiceSocket类负责接收从客户端发送来的数据包,客户端第一次发送过来的数据包和后期的通讯数据都是由它负责接收的。新建实例时会创建一个 Socket 套接字和一个SocketAsyncEventArgs,并且对其进行相应的初始化。OnDataReceived 事件用于计算收到了多少数据。

代码

class Program
{
static string serverIp;
static string name = string.Empty;
static IPEndPoint ipe;
static Socket server;
static int port;
static int port2;
static Mutex mutex = new Mutex();
static void Main(string[] args)
{
Console.WriteLine("输入服务器IP地址");
serverIp = Console.ReadLine();
Console.WriteLine("输入端口");
port = int.Parse(Console.ReadLine());
Console.WriteLine("输入传输端口");
port2 = int.Parse(Console.ReadLine());
ipe = new IPEndPoint(IPAddress.Parse(serverIp), port);

while (run()) ;
Console.ReadLine();
}

//循环测试,如果输入连接数小于0将退出
static bool run()
{

int txtNum;
Console.WriteLine("输入最大连接数");
txtNum = int.Parse(Console.ReadLine());

for (int i = 0; i < txtNum; i++)
{
StartSend(txtNum);
}
return txtNum > 0;
}

/// <summary>
/// 创建一个新的Socket 和SocketAsyncEventArgs 对象,并开始向服务器端发送数据
/// </summary>
/// <param name="txtNum"></param>
static void StartSend(int txtNum)
{
server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
SocketAsyncEventArgs socketAsyncEventArgs = new SocketAsyncEventArgs();

string welcome = "测试"  + ",申请链接,";
byte[] data = new byte[1024];
data = Encoding.Unicode.GetBytes(welcome);

socketAsyncEventArgs.SetBuffer(data, 0, data.Length);
socketAsyncEventArgs.UserToken = server;
socketAsyncEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(socketAsyncEventArgs_Completed);

//向服务器端发送第一个数据包,相当于申请链接
server.SendTo(data,ipe );
//向服务器进行异步的数据发送
Send(socketAsyncEventArgs);
Thread.Sleep(20);

}

static void Send(SocketAsyncEventArgs e)
{
Socket s = e.UserToken as Socket;
e.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(serverIp), port2);
s.SendToAsync(e);

}

static void socketAsyncEventArgs_Completed(object sender, SocketAsyncEventArgs e)
{
Thread.Sleep(3000);
//循环的发送数据
Send(e);
}

}


测试

  本次的测试目标是:10万个客户端和服务器程序通讯时的运行情况。因为每台电脑的端口有限最大也就65535 ,而且我们也不可能开到这么多个套接字,所以我就在不同的机器上运行了上面的测试用客户端程序。

  测试环境:局域网。

  服务器端程序运行环境:Win7 操作系统、2GB内存、CPU:P core E5200 2.50GHz。

客户端环境:3台电脑、一台win7 两台Win2003。
运行服务器端程序设置两个端口,并设定最大的客户端数为110000。下面是客户端没有发送数据时的计数器截图

  接下来就是在各台电脑上奔走,运行客户端的测试程序向服务器发送数据包。为了加快并发数,实际上我实在每台电脑上运行多个客户端程序。下图是在客户端连接数到达6万时的计数器情况。

  整个过程中Handle Count 和Private Bytes总在上升当中(也有可能是因为不断的有新来的客户端加入的原因),程序可能有Handle Leak和Memory Leak。

源码下载

UdpSocketAsyncEventArgs
  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: