2
0

UdpLogger.cs 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. using Newtonsoft.Json;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Net;
  5. using System.Net.NetworkInformation;
  6. using System.Net.Sockets;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. namespace FastGithub.UI
  10. {
  11. static class UdpLogger
  12. {
  13. private static readonly byte[] buffer = new byte[ushort.MaxValue];
  14. private static readonly Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp);
  15. /// <summary>
  16. /// 获取日志端口
  17. /// </summary>
  18. public static int Port { get; } = GetAvailableUdpPort(38457);
  19. static UdpLogger()
  20. {
  21. socket.Bind(new IPEndPoint(IPAddress.Loopback, Port));
  22. }
  23. /// <summary>
  24. /// 获取可用的随机Udp端口
  25. /// </summary>
  26. /// <param name="minValue"></param>
  27. /// <param name="addressFamily"></param>
  28. /// <returns></returns>
  29. private static int GetAvailableUdpPort(int minValue, AddressFamily addressFamily = AddressFamily.InterNetwork)
  30. {
  31. var hashSet = new HashSet<int>();
  32. var tcpListeners = IPGlobalProperties.GetIPGlobalProperties().GetActiveUdpListeners();
  33. foreach (var endpoint in tcpListeners)
  34. {
  35. if (endpoint.AddressFamily == addressFamily)
  36. {
  37. hashSet.Add(endpoint.Port);
  38. }
  39. }
  40. for (var port = minValue; port < IPEndPoint.MaxPort; port++)
  41. {
  42. if (hashSet.Contains(port) == false)
  43. {
  44. return port;
  45. }
  46. }
  47. throw new ArgumentException("当前无可用的端口");
  48. }
  49. public static async Task<UdpLog?> GetUdpLogAsync()
  50. {
  51. EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
  52. var taskCompletionSource = new TaskCompletionSource<int>();
  53. socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref remoteEP, EndReceiveFrom, taskCompletionSource);
  54. var length = await taskCompletionSource.Task;
  55. var json = Encoding.UTF8.GetString(buffer, 0, length);
  56. return JsonConvert.DeserializeObject<UdpLog>(json);
  57. }
  58. private static void EndReceiveFrom(IAsyncResult ar)
  59. {
  60. EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
  61. var length = socket.EndReceiveFrom(ar, ref remoteEP);
  62. var taskCompletionSource = (TaskCompletionSource<int>)ar.AsyncState;
  63. taskCompletionSource.TrySetResult(length);
  64. }
  65. }
  66. }