[英]Sending/receiving UDP packets on thousands of port numbers
我對客戶端/服務器應用程序有一組要求,如下所示:
1)程序向正在偵聽預定義UDP端口的主機發送狀態檢查消息。 該消息在操作系統給定的源端口號上發送。
2)程序需要偵聽在步驟1中啟動的源端口號,以接收來自遠程主機的響應。 因此,程序必須同時偵聽數千個端口。
3)此過程需要每分鍾數千個主機進行
在下面,我創建了一個示例示例,該示例向Echo Server發送大量請求以模仿此行為。 我面臨的問題是,盡管我在從遠程主機接收到數據后關閉了每個套接字,但是在大約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);
}
}
我認為,就性能和簡單性而言,最好的方法是在以下位置之間的任何位置簡單地使用單個端口號:
1025 - 65553
然后,當偵聽來自其他對等方的數千條消息時,它們還會發送到預定義的已知端口號,您可以異步處理它們。
要收聽已知的端口號,在這種情況下為60000:
mySocket.Bind(new IPEndPoint(IPAddress.Any, 60000));
也不要在每次操作后關閉插座! 保持打開狀態並重新使用它。
正確編寫后,它將可以在.Net和OS的公園中漫步,從而滿足您的需求。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.