private async Task<byte[]?> ExecuteUdpRequest2(Uri uri, byte[] message)
{
byte[]? data = null;
if (uri == null) throw new ArgumentNullException(nameof(uri));
if (message == null) throw new ArgumentNullException(nameof(message));
int port = await Torrent.PortList.AwaitOpenPort();
IPEndPoint ep = new IPEndPoint(IPAddress.Any, port);
try
{
using UdpClient udpClient = new(ep);
Logger.Log($"Listening on : {ep}");
udpClient.Client.SendTimeout = (int)TimeSpan.FromSeconds(5).TotalMilliseconds;
udpClient.Client.ReceiveTimeout = (int)TimeSpan.FromSeconds(5).TotalMilliseconds;
Logger.Log($"sending message to {uri.Host}, returning.", source: "UdpRequest");
int numBytesSent = await udpClient.SendAsync(message, message.Length, uri.Host, uri.Port);
Logger.Log($"Sent: {numBytesSent}", source: "UdpRequest");
UdpReceiveResult? res;
//var res = udpClient.BeginReceive(null, null);
try
{
CancellationTokenSource cts = new CancellationTokenSource();
var timer = new Timer(state => cts.Cancel(), null, 5000, Timeout.Infinite);
res = await udpClient.ReceiveAsync(cts.Token);
}
catch (OperationCanceledException ex)
{
res = null;
}
// begin recieve right after request
if (res != null && res?.Buffer != null && res?.Buffer.Length > 0)
{
Logger.Log($"Recieved message from endpoint, returning.", source: "UdpRequest");
data = res?.Buffer;
}
else
{
Logger.Log($"No Bytes Recieved from UdpRequest", source: "UdpRequest");
// here the client just times out.
}
}
catch (SocketException ex)
{
Logger.Log($"Failed UDP tracker message to {uri} for torrent {Torrent.InfoHash}: {ex.Message}");
}
Torrent.PortList.SetPortUnused(port);
return data;
}