我对客户端/服务器应用程序有一组要求,如下所示:
1) 程序向正在侦听预定义 UDP 端口的主机发送状态检查消息。此消息在 OS 给定的源端口号上发送。
2)程序需要监听步骤1中发起的源端口号来接收远程主机的响应。因此程序必须同时监听数千个端口。
3)这个过程需要为每分钟数千台主机完成
下面我创建了一个示例示例,它向 Echo 服务器发送大量请求以模仿这种行为。我面临的问题是,虽然我在从远程主机接收数据后关闭了每个套接字,但在大约 16,000 个请求之后抛出异常,说系统缺乏足够的缓冲区空间或队列已满。
什么是实现这些要求的方法?
public void SendChecks()
{
IPEndPoint ip = new IPEndPoint(IPAddress.Parse("1.1.1.1"), 7);
for (int i = 0; i < 200000; i++)
{
Socket _UdpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
stateobject so = new stateobject(_UdpSocket);
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint tempRemoteEP = (EndPoint)sender;
_UdpSocket.Bind(tempRemoteEP);
string welcome = "Hello";
byte[] data = new byte[5];
data = Encoding.ASCII.GetBytes(welcome);
_UdpSocket.BeginSendTo(data, 0, data.Length, SocketFlags.None, ip, new AsyncCallback(OnSend), _UdpSocket);
//Start listening to the message send by the user
EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
_UdpSocket.BeginReceiveFrom(so.buffer, 0, so.buffer.Length, SocketFlags.None, ref newClientEP, new AsyncCallback(DoReceiveFrom), so);
}
}
private void DoReceiveFrom(IAsyncResult ar)
{
try
{
stateobject so = (stateobject)ar.AsyncState;
Socket s = so.sock;
// Creates a temporary EndPoint to pass to EndReceiveFrom.
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint tempRemoteEP = (EndPoint)sender;
int read = s.EndReceiveFrom(ar, ref tempRemoteEP);
so.sb.Append(Encoding.ASCII.GetString(so.buffer, 0, read))
//All the data has been read, so displays it to the console.
string strContent;
strContent = so.sb.ToString();
Console.WriteLine(String.Format("Read {0} byte from socket" +"data = {1} ", strContent.Length, strContent));
s.Close();
s.Dispose();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
private void OnSend(IAsyncResult ira)
{
Socket s = (Socket)ira.AsyncState;
Console.WriteLine("Sent Data To Sever on port {0}",((IPEndPoint)s.LocalEndPoint).Port);
s.EndSend(ira);
}
}