UdpLogger.cs 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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. var log = JsonConvert.DeserializeObject<UdpLog>(json);
  57. if (log != null)
  58. {
  59. log.Message = log.Message.Replace("\"", null);
  60. }
  61. return log;
  62. }
  63. private static void EndReceiveFrom(IAsyncResult ar)
  64. {
  65. EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
  66. var length = socket.EndReceiveFrom(ar, ref remoteEP);
  67. var taskCompletionSource = (TaskCompletionSource<int>)ar.AsyncState;
  68. taskCompletionSource.TrySetResult(length);
  69. }
  70. }
  71. }