我对客户端/服务器应用程序有一组要求,如下所示:
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);
        }
    }